无法设置对象类的属性 [英] Can't set attributes of object class

查看:102
本文介绍了无法设置对象类的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我与Python玩弄一边回答<一个href=\"http://stackoverflow.com/questions/1528932/how-to-create-inline-objects-with-properties-in-python/\">this问题,我发现这是无效的:

So, I was playing around with Python while answering this question, and I discovered that this is not valid:

o = object()
o.attr = 'hello'

由于一个 AttributeError的:'对象'对象有没有属性'ATTR。然而,从对象继承的任何类,它是有效的:

due to an AttributeError: 'object' object has no attribute 'attr'. However, with any class inherited from object, it is valid:

class Sub(object):
    pass

s = Sub()
s.attr = 'hello'

印刷 s.attr 显示'你好'预期。为什么会出现这样的情况?在Python语言规范什么规定,你不能分配属性香草对象?

Printing s.attr displays 'hello' as expected. Why is this the case? What in the Python language specification specifies that you can't assign attributes to vanilla objects?

推荐答案

的实例对象做的不可以随身携带 __字典__ - 如果它这样做了,可怕的循环依赖问题(因为字典之前,像其他大多数的一切,从<$ C $继承C>对象 ;-),这将鞍的每个的对象在Python有字典,这将意味着的许多的每个对象的字节的开销,目前没有或需要一个字典(基本上,没有随意分配的属性不具备或需要的字典中的所有对象)。

An instance of object does not carry around a __dict__ -- if it did, before the horrible circular dependence problem (since dict, like most everything else, inherits from object;-), this would saddle every object in Python with a dict, which would mean an overhead of many bytes per object that currently doesn't have or need a dict (essentially, all objects that don't have arbitrarily assignable attributes don't have or need a dict).

例如,采用优 pympler 项目(您可以通过从的这里),我们可以做一些测量...

For example, using the excellent pympler project (you can get it via svn from here), we can do some measurements...:

>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16

您不希望每 INT 占用144个字节,而不是仅仅16,右 - ?)

You wouldn't want every int to take up 144 bytes instead of just 16, right?-)

现在,当你犯了一个类(无论从那个继承),事物的变化...

Now, when you make a class (inheriting from whatever), things change...:

>>> class dint(int): pass
... 
>>> asizeof.asizeof(dint(23))
184

...的 __ __字典的现在又增加了(加,多一点开销) - 因此实例可以拥有任意的属性,但是你付出相当的空间成本灵活性。

...the __dict__ is now added (plus, a little more overhead) -- so a dint instance can have arbitrary attributes, but you pay quite a space cost for that flexibility.

所以,如果你想 INT s的只是有一个的额外属性 foobar的。 ..?这是一个难得的需要,但是Python的确为目的的特殊机制...

So what if you wanted ints with just one extra attribute foobar...? It's a rare need, but Python does offer a special mechanism for the purpose...

>>> class fint(int):
...   __slots__ = 'foobar',
...   def __init__(self, x): self.foobar=x+100
... 
>>> asizeof.asizeof(fint(23))
80

......不是的非常的形成微小作为 INT ,你要知道! (甚至两个 INT S,一个和一个 self.foobar - 第二个可以被重新分配),但肯定远远好

...not quite as tiny as an int, mind you! (or even the two ints, one the self and one the self.foobar -- the second one can be reassigned), but surely much better than a dint.

在这个类有 __插槽__ 特殊的属性(字符串序列),那么语句(更precisely,默认元类,键入)做的不可以装备该类的每一个实例与 __字典__ (因此有任意属性的能力),只是一个有限的,刚性集插槽(可各持一个参考一些对象主要地方)用给定的名字。

When the class has the __slots__ special attribute (a sequence of strings), then the class statement (more precisely, the default metaclass, type) does not equip every instance of that class with a __dict__ (and therefore the ability to have arbitrary attributes), just a finite, rigid set of "slots" (basically places which can each hold one reference to some object) with the given names.

在换回失去的灵活性,你获得了很多每个实例的字节(前提是你有闲逛身边实例不计其数可能有意义的,但是,有的用例的)。

In exchange for the lost flexibility, you gain a lot of bytes per instance (probably meaningful only if you have zillions of instances gallivanting around, but, there are use cases for that).

这篇关于无法设置对象类的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆