草庐IT

python - 在 Python 中结合棉花糖模式定义和 OO 的最佳实践是什么?

coder 2023-05-27 原文

关闭。这个问题是opinion-based .它目前不接受答案。












想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.

3年前关闭。




Improve this question




假设在 marshmallow 中定义了一个简单的模式

class AddressSchema(Schema):
    street=fields.String(required=True)
    city=fields.String(required=True)
    country=fields.String(default='USA')

class PersonSchema(Schema):
    name=fields.String(required=True)
    address=fields.Nested(AddressSchema())

这里的用例是使用内存对象的应用程序,以及序列化/反序列化到 JSON,即没有 SQL 数据库。

使用标准 json库我可以解析符合此模式的 JSON 对象,并以诸如 person1['address']['city'] 的方式访问对象。 ,但是在冗长的语法中使用容易打错字的字符串有些不尽人意。

手工制作的OO模型

我可以定义一个并行的 OO 模型,并用 @post_load 注释我的模式装饰器,例如:
class Address(object):
    def __init__(self, street, city, country='USA'):
        self.street=street
        self.city=city
        self.country=country

class Person(object):
    def __init__(self, street, city=None):
        self.street=street
        self.city=city

但是重复不是很好(我什至没有在模式中包含描述)。

没有OO模型

可以说显式 OO 模型并没有买多少——它是基本的数据访问器,没有行为。我可以使用 jsobject 获得一些语法糖,这样我就可以写例如 person1.address.city .但这似乎也不太对。作为开发人员,我没有明确的 python 类 API 来确定要使用的字段,我可以引用棉花糖模式,但这感觉非常间接。

代码生成

从棉花糖模式定义生成上面的 OO 代码是相当容易的。我很惊讶似乎没有这样的图书馆。也许代码生成被认为是非常非pythonic的?它当然只适用于数据访问风格的类定义;添加非通用行为将是严格禁止的。

对于代码的用户,他们不需要知道使用了代码生成方法 - 一切都将通过显式 API 存在,文档与 readthedocs 等中的其余代码一起可见。

动态类

另一种方法是从棉花糖定义派生的动态类。同样,据我所知,没有这样的库(尽管 python 中动态类生成方法的范围令人印象深刻,但我可能错过了一些)。可以说,与 jsobjects 方法相比,这不会给您带来太多好处,但可能有一些优势 - 可以将其与一些具有定义行为的显式代码交织在一起。动态方法的缺点是在 Python 世界中显式优于隐式。

什么是最pythonic的?

这里缺少库意味着我要么没有找到任何东西,要么没有以适当的 Pythonic 方式看待这个问题。我很高兴为 pypi 贡献一些东西,但在添加另一个元 OO 库之前,我想确保我已经在这里做了尽职调查。

最佳答案

你的问题很模糊,我的回答也是如此,而且很主观,我希望没关系。我只是一个花一天时间阅读 python 中的序列化选项的家伙。

我认为 Marshmallow 从根本上来说是非 Pythonic 的,并且没有很好的方法来使用它,我不打算使用它。我将给出对我来说是两个明确的例子。

  • 您有一个类,该类将其他对象的混合类型列表作为字段。这是python,所以你可以这样做。在棉花糖中,您无法 native 或巧妙地处理此问题。有一个非常自然的解决方案,即使用已注册的序列化程序放下/打开类列表。但是在 Marshmallow 中,您必须编写自己的代码并更改每个可能的类的序列化程序,以确保它在传递给嵌套 func 的某些内容中注册。它没有为类注册序列化程序,您必须添加它。 Issue describing.
  • 您想将字符串的混合(文字)字典序列化为未知类。这与上面的几乎相同,您必须自己实现它。另外,您必须为您想要执行此操作的每个原语编写一个序列化程序/de 自己。他们为原语编写了字段而不是模式的代码,对我来说,这不是包含电池或一种明显的方式。

  • 通用的序列化库有点像一个深坑,因为你真正谈论的东西需要类型系统的元素、解析器和图遍历算法一次性完成。默认情况下,Marshmallow 不进行递归解析,因此它在第 (2) 点失败。在第 (1) 点,(有点因为 2),它要么需要大量的黑客攻击,要么需要您接受类似 java 的类型系统(一切都是已知的枚举类型)。

    您询问了一般的序列化库,我发现库 Camel 很有趣,并且有关于它的博客文章。对于泡菜,有一个强大的扩展名为 dill和处理 versioning 的 mixin

    关于python - 在 Python 中结合棉花糖模式定义和 OO 的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45805767/

    有关python - 在 Python 中结合棉花糖模式定义和 OO 的最佳实践是什么?的更多相关文章

    1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

      类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

    2. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

      我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

    3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

      关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

    4. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

      我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

    5. ruby-on-rails - 结合 meta_search 与 acts_as_taggable_on - 2

      我在开发的Rails3网站的一些搜索功能上遇到了一个小问题。我有一个简单的Post模型,如下所示:classPost我正在使用acts_as_taggable_on来更轻松地向我的帖子添加标签。当我有一个标记为“rails”的帖子并执行以下操作时,一切正常:@posts=Post.tagged_with("rails")问题是,我还想搜索帖子的标题。当我有一篇标题为“Helloworld”并标记为“rails”的帖子时,我希望能够通过搜索“hello”或“rails”来找到这篇帖子。因此,我希望标题列的LIKE语句与acts_as_taggable_on提供的tagged_with方法

    6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

      我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

    7. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

      我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

    8. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

      为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

    9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

      我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

    10. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

      我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

    随机推荐