【问题标题】:Standard Python base class as a container for arbitrary attributes标准 Python 基类作为任意属性的容器
【发布时间】:2016-01-04 19:43:07
【问题描述】:

之所以问这个问题,是因为它似乎是一种经常出现的模式,我想知道是否有人知道支持这个的标准库功能,或者可能做类似事情的单线。

如果我想定义一个用于传递数据的类,它可以包含任意属性,在构造时进行设置,我可以这样做:

>>> class Splat:
        def __init__(self, **args):
            for k, v in args:
                setattr(self, k, v)

然后像这样使用它:

>>> s = Splat(attr1='burp', attr2='gurt', attr3='sint')
>>> vars(s)
{'attr2': 'gurt', 'attr3': 'sint', 'attr1': 'burp'}

这是我在 python 标准库中看到的一种模式(ssl.wrapSocket 或者如果有记忆的话,可以在其中使用),我想一般来说它会足够有用,可能成为我可以利用的常用 Python 习语或 mixin,而不必在需要时创建自己的。

我知道当我需要时,它只是一个四线,但为了节约起见,我想知道我是否可以使用 0 或至少 1 线的变体。可能是这样的:

s = TheBaseClass({'attr2': 'gurt', 'attr3': 'sint', 'attr1': 'burp'})

class Splat(TheBaseClass):
    pass

有些人可能会很快跳进去说“使用字典”,但我正在考虑可能希望模拟现有对象类型(鸭子类型)并推断它是特定的用例“type”(就像这个功能只是用作 mixin)。

编辑:类似地,s = type('Splat', (), {'attr2': 'gurt', 'attr3': 'sint', 'attr1': 'burp'}) 这样的构造的问题是我无法声明它,或者在类型安全方面获得太多...

【问题讨论】:

标签: python


【解决方案1】:

这有点像用推土机敲钉子......但是argparse 定义了一个Namespace 类来执行此操作:

import argparse
print(argparse.Namespace(a=1, b=2))

你总是可以从中得到:

import argparse
class X(argparse.Namespace): pass
print(X(a=1, b=2))

但是,我真的不建议您这样做,因为它有点……恶心……

至少你可以免费获得__str____repr__

【讨论】:

  • @robert 你的意思是用于导入argparse 的额外行? :D
  • 对不起 - 实际上我正在重新阅读它......是的,我认为这可能是我正在寻找的!
  • 完全符合我的要求:)
  • 我实际上对此非常满意 - 它就像一个新玩具 - 完全不知道你为什么说它很恶心 - 查看其实现的源代码,除了什么之外没有任何额外的东西需要..也可以将默认值设置为类变量。如果只有一种指定强制属性的好方法....
  • @robert 这很简单;只需将其子类化并在 __init__ 中定义它们
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 2020-05-29
  • 2016-12-02
  • 2020-01-04
  • 2012-12-05
  • 2020-01-01
相关资源
最近更新 更多