python中的struct对象

Ste*_*ini 11 python

我想创建一个一次性"struct"对象来保存各种状态标志.我的第一个方法就是这个(javascript风格)

>>> status = object()
>>> status.foo = 3  
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
Run Code Online (Sandbox Code Playgroud)

绝对不是我的预期,因为这有效:

>>> class Anon: pass
... 
>>> b=Anon()
>>> b.foo = 4
Run Code Online (Sandbox Code Playgroud)

我想这是因为object()没有__dict__.我不想使用字典,假设我不想创建Anon对象,还有其他解决方案吗?

Ale*_*lli 25

制作"可以分配/获取属性的通用对象"的最简洁方法可能是:

b = lambda:0
Run Code Online (Sandbox Code Playgroud)

正如大多数其他答案所指出的那样,还有很多其他的方法,但是为了简洁而难以击败这个方面(lambda:0object()...的数字完全相同; ;-).

  • 只有你不计算解释它是什么的角色!:d (22认同)
  • 起初,这令我难以置信.但它实际上很简单.`lambda`创建一个函数对象; 这个碰巧是一个返回0的简单函数.函数对象具有某些属性,其中包括`func_dict`成员.这是有效的,因为它适用于任何函数对象; 您可以将值绑定到与任何函数对象关联的名称.我用它来提供可以在调用函数时使用的"枚举"标志:`foo(0,foo.ALTERNATE_MODE)`这个结果示例显示调用一个带有可选标志的函数,该标志请求某种替代模式. (4认同)
  • @Stefano,谢谢!@gnibbler,lambda 足够神秘,你不必解释,你只需在空中做出神秘的手指手势,每个人都会害怕地后退(可选地,黑暗低语“lambda,终极......!”,http:// lambda-the-ultimate.org/,和/或查看 http://en.wikipedia.org/wiki/Lambda 以获取许多其他晦涩的参考资料)。 (2认同)
  • 呃哦......马爹利被颠覆了,走到了黑暗面:-( (2认同)

Esc*_*alo 15

Python官方文档:

9.7.什物

有时,使用类似于Pascal"record"或C"struct"的数据类型是很有用的,将一些命名数据项捆绑在一起.一个空的类定义可以很好地完成:

class Employee:
    pass

john = Employee() # Create an empty employee record

# Fill the fields of the record 
john.name = 'John Doe' 
john.dept = 'computer lab' 
john.salary = 1000
Run Code Online (Sandbox Code Playgroud)

这似乎很自然而简单:Pythonic.记住禅!"简单比复杂更好"(第3号)和"如果实施容易解释,那可能是个好主意"(编号11)

另外,a struct只不过是class公共成员(即,struct{};并且class{public:};完全相同(例如,C++)).您是否应该考虑这一点并避免在Python程序中使用人工构造?Python应该是可读的,可维护的,易于理解的.

  • 呃,这是旧的文档,他们应该清理它.此示例代码创建"旧式类".这不是推荐的练习,在Python 3.x中它甚至不起作用.要做一个完整的例子作为一个可以在Python 3.x中工作的新式类:`class Employee(object):pass`这就是你所要做的,只是从`object`继承并且你有一个新式的类. (3认同)
  • @ user273158,答案就像以前一样好.我完全错误地认为Python 3.x中禁止使用这种语法; 相反,在Python 3.x中,这种语法完全等同于说新类继承自`object`.如果我可以编辑我的评论来纠正它,我会这样做.我想删除它,但由于其他评论引用它,我认为这会令人困惑. (3认同)
  • @nd和@steveha你不需要在Python 3中显式地继承对象.在Python 3中,继承自object是默认的.没有旧式的课程. (2认同)

ste*_*eha 9

我曾经有过同样的问题.我在邮件列表中问过它,Alex Martelli指出这object是Python中所有继承的基础; 如果object()用自己的字典创建了一个类实例,那么Python中的每个对象都必须有自己的字典,这会浪费内存.例如,TrueFalse是对象; 显然他们对自己的词典没有任何需要!

如果有某种内置的Python功能,我会很高兴我可以说:

x = struct()
x.foo = 1
x.bar = 2
Run Code Online (Sandbox Code Playgroud)

但写下来是微不足道的struct():

class struct(object):
    pass
Run Code Online (Sandbox Code Playgroud)

或者你可以做一个稍微复杂的一个:

class struct(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
Run Code Online (Sandbox Code Playgroud)

更复杂的一个让你这样做:

x = struct(foo=1, bar=2)
print(x.foo) # prints 1
print(x.bar) # prints 2
x.baz = 3
print(x.baz) # prints 3
Run Code Online (Sandbox Code Playgroud)

但是编写它是如此微不足道struct(),我想它不值得添加到语言中.也许我们应该推动将标准功能添加到collections模块或其他东西.

  • 为了鼓励pythonic思考和可读代码,你可以大写`struct`.`Struct`更明显是一个`class`而不是内置函数.但是我很欣赏你的想法,你正在创建一个非常类似于内置`object`类的新的个人"内置".小写的`struct`看起来更简单. (2认同)

Mar*_*ans 5

我个人认为最干净的解决方案是您已经猜到的:

class Scratch(object):
    pass

s = Scratch()
s.whatever = 'you want'
Run Code Online (Sandbox Code Playgroud)

我知道你说过你不想要 a __dict__,但这让我感到困惑,因为我看不出有理由关心它。您不必引用__dict__,这是一个内部 Python 实现细节。无论如何,Python 中允许动态添加属性的任何实例都会有一个,__dict__因为 Python 就是这样处理动态属性的。即使实例是以非常聪明的方式创建的,它也会有一个__dict__.

如果您还没有这样做,我建议您阅读PEP 20PEP 8。并不是说 PEP 与您的问题直接相关,但我认为以Pythonic 的方式开始使用 Python 很有用。