python python中的结构体对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1878710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
struct objects in python
提问by Stefano Borini
I wanted to create a throwaway "struct" object to keep various status flags. My first approach was this (javascript style)
我想创建一个一次性的“结构”对象来保留各种状态标志。我的第一种方法是这个(javascript 风格)
>>> status = object()
>>> status.foo = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
Definitely not what I expected, because this works:
绝对不是我所期望的,因为这有效:
>>> class Anon: pass
...
>>> b=Anon()
>>> b.foo = 4
I guess this is because object() does not have a __dict__
. I don't want to use a dictionary, and assuming I don't want to create the Anon object, is there another solution ?
我想这是因为 object() 没有__dict__
. 我不想使用字典,并且假设我不想创建 Anon 对象,还有其他解决方案吗?
回答by Alex Martelli
The most concise way to make "a generic object to which you can assign/fetch attributes" is probably:
制作“您可以为其分配/获取属性的通用对象”的最简洁方法可能是:
b = lambda:0
As most other answers point out, there are many other ways, but it's hard to beat this one for conciseness (lambda:0
is exactly the same number of characters as object()
...;-).
正如大多数其他答案所指出的那样,还有许多其他方法,但为了简洁,很难击败这个方法(lambda:0
与object()
... ;- 的字符数完全相同)。
回答by Escualo
From the Python Official Documentation:
来自Python 官方文档:
9.7. Odds and Ends
Sometimes it is useful to have a data type similar to the Pascal “record” or C “struct”, bundling together a few named data items. An empty class definition will do nicely:
9.7. 什物
有时,使用类似于 Pascal“记录”或 C“结构”的数据类型将一些命名数据项捆绑在一起很有用。一个空的类定义会很好:
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
This seems natural and simple: Pythonic. Remember the Zen!"Simple is better than complex" (number 3) and "If the implementation is easy to explain, it may be a good idea" (number 11)
这看起来自然而简单:Pythonic。记住禅!“简单胜于复杂”(第 3 条)和“如果实现易于解释,这可能是一个好主意”(第 11 条)
In addition, a struct
is nothing but a class
with public members (i.e., struct{};
and class{public:};
are the exact same thing (in, say, C++)). Shouldn't you consider this and avoid artificial constructs in your Python program? Python is supposed to be readable, maintainable, and easy to understand.
此外,astruct
只不过是class
具有公共成员的 a(即,struct{};
和class{public:};
是完全相同的东西(例如,在 C++ 中))。您不应该考虑这一点并避免在您的 Python 程序中使用人工构造吗?Python 应该是可读的、可维护的和易于理解的。
回答by steveha
I had the same question once. I asked it in a mailing list, and Alex Martelli pointed out that object
is the basis of all inheritance in Python; if object()
created a class instance with its own dictionary, then every object in Python would have to have its own dictionary, and that would waste memory. For example, True
and False
are objects; clearly they don't have any need for their own dictionaries!
我曾经有过同样的问题。我在邮件列表中询问了它,Alex Martelli 指出这object
是 Python 中所有继承的基础;如果object()
用自己的字典创建一个类实例,那么 Python 中的每个对象都必须有自己的字典,这会浪费内存。例如,True
和False
是对象;显然他们不需要自己的字典!
I would be happy if there was some sort of built-in Python feature where I could just say:
如果有某种内置的 Python 功能,我会很高兴我可以说:
x = struct()
x.foo = 1
x.bar = 2
But it is trivial to write struct()
:
但是写起来很简单struct()
:
class struct(object):
pass
Or you could do a slightly more complex one:
或者你可以做一个稍微复杂一点的:
class struct(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
The more complex one lets you do this:
更复杂的一个可以让你做到这一点:
x = struct(foo=1, bar=2)
print(x.foo) # prints 1
print(x.bar) # prints 2
x.baz = 3
print(x.baz) # prints 3
But it is so trivial to write struct()
that I guess it wasn't deemed worth adding to the language. Maybe we should push to have a standard feature added to collections
module or something.
但是写起来太琐碎了struct()
,我想它被认为不值得添加到语言中。也许我们应该推动将标准功能添加到collections
模块或其他东西中。
回答by Mark Evans
I personally think that the cleanest solution is what you already guessed:
我个人认为最干净的解决方案是您已经猜到的:
class Scratch(object):
pass
s = Scratch()
s.whatever = 'you want'
I know you said that you don't want a __dict__
, but that confuses me as I can't see a reason to care about that. You don't have to reference __dict__
, that is an internal Python implementation detail. Anyway, any instance in Python that allows dynamically adding attributes will have a __dict__
because that's how Python does dynamic attributes. Even if the instance is created in a really clever way, it will have a __dict__
.
我知道你说过你不想要 a __dict__
,但这让我感到困惑,因为我看不出有理由关心它。您不必引用__dict__
,这是一个内部 Python 实现细节。无论如何,Python 中允许动态添加属性的任何实例都会有一个,__dict__
因为 Python 就是这样处理动态属性的。即使实例是以非常聪明的方式创建的,它也会有一个__dict__
.
If you have not already done so, I recommend reading PEP 20and PEP 8. Not that the PEPs directly relate to your question, but I think it's useful in starting to use Python in a Pythonicmanner.
如果您还没有这样做,我建议您阅读PEP 20和PEP 8。并不是说 PEP 与您的问题直接相关,但我认为以Pythonic 的方式开始使用 Python 很有用。
回答by hobs
Of course there's always a namedtuple
. It's cheap and fast, but immutable -- you must know your attribute names and values in advance, and you can't alter their values later. But at least it has the struct/object attribute getters. And it'll work with Python 2 and 3
当然,总有一个namedtuple
。它既便宜又快速,但不可变——您必须提前知道您的属性名称和值,并且以后不能更改它们的值。但至少它有 struct/object 属性 getter。它适用于 Python 2 和 3
>>> from collections import namedtuple
>>> Status = namedtuple('Status', 'a b')
>>> s = Status(a=1, b=2)
>>> s.a + s.b
3
回答by John La Rooy
Try this
试试这个
>>> status=type('status',(object,),{})()
>>> status.foo=3
>>> status.foo
3
You don't have to give the class a name if you don't want to
如果您不想,则不必为类命名
>>> status=type('',(object,),{})()
>>> status.__class__.__name__
''
回答by jpsimons
The mystery here is the difference between objectsand class instances.
这里的奥秘在于对象和类实例之间的区别。
In Python, everything is an object. Classes are objects, integers are objects, types are objects, and class instances are objects. When you say object()
you're getting a plain base-level object. It's nothing. Completely useless. Lower level than anything else you can reference in Python.
在 Python 中,一切都是对象。类是对象,整数是对象,类型是对象,类实例是对象。当你说object()
你得到一个普通的基础级对象时。没什么。完全没用。比您在 Python 中可以引用的任何其他内容都低。
You probably thought calling object()
gives you a class instance. Which is understandable, because you probably thought object
is a class. It's not. Even though you might think so since it's the base "class" used for new-style class definitions like:
您可能认为调用object()
会为您提供一个类实例。这是可以理解的,因为你可能认为object
是一个类。不是。尽管您可能会这么认为,因为它是用于新式类定义的基本“类”,例如:
class MyClass(object):
pass
object
is in fact a type(like how str
and int
are types). When you call object()
you're not constructing a class instance, your instantiating a special type of object. But in object
's case, it's special in how completely blahit is.
object
实际上是一种类型(比如 howstr
和int
are 类型)。当您调用时,object()
您不是在构造类实例,而是在实例化特殊类型的对象。但在object
's 的情况下,它的特殊之处在于它是多么的完全废话。
Only class instances have the special ability to tack things on with dot notation. That's not a general property of all objects. Imagine if that were the case! You could do crazy stuff like adding properties to strings:
只有类实例具有使用点符号添加内容的特殊能力。这不是所有对象的一般属性。想象一下,如果是这样的话!你可以做一些疯狂的事情,比如向字符串添加属性:
s = "cat"
s.language = "english"
Obviously you can't do that.
显然你不能这样做。
回答by Pedro Cattori
If you want the semantics of a Javascript object, you could consider using the namespaces library. You just need to pip install namespaces
first.
如果您想要 Javascript 对象的语义,您可以考虑使用namespaces 库。你只需pip install namespaces
要先。
>>> import namespaces as ns
>>> b = ns.Namespace()
>>> b.foo = 4
>>> b
Namespace(foo=4)
full disclaimer: I am the author of the namespaces
library.
完全免责声明:我是namespaces
图书馆的作者。