• <tfoot id='9E9l0'></tfoot><legend id='9E9l0'><style id='9E9l0'><dir id='9E9l0'><q id='9E9l0'></q></dir></style></legend>
      <bdo id='9E9l0'></bdo><ul id='9E9l0'></ul>

      <i id='9E9l0'><tr id='9E9l0'><dt id='9E9l0'><q id='9E9l0'><span id='9E9l0'><b id='9E9l0'><form id='9E9l0'><ins id='9E9l0'></ins><ul id='9E9l0'></ul><sub id='9E9l0'></sub></form><legend id='9E9l0'></legend><bdo id='9E9l0'><pre id='9E9l0'><center id='9E9l0'></center></pre></bdo></b><th id='9E9l0'></th></span></q></dt></tr></i><div id='9E9l0'><tfoot id='9E9l0'></tfoot><dl id='9E9l0'><fieldset id='9E9l0'></fieldset></dl></div>

        <small id='9E9l0'></small><noframes id='9E9l0'>

      1. 无法在“对象"实例上设置属性班级

        时间:2023-09-13
          <tbody id='RNBde'></tbody>
            1. <tfoot id='RNBde'></tfoot>
                <bdo id='RNBde'></bdo><ul id='RNBde'></ul>

                <i id='RNBde'><tr id='RNBde'><dt id='RNBde'><q id='RNBde'><span id='RNBde'><b id='RNBde'><form id='RNBde'><ins id='RNBde'></ins><ul id='RNBde'></ul><sub id='RNBde'></sub></form><legend id='RNBde'></legend><bdo id='RNBde'><pre id='RNBde'><center id='RNBde'></center></pre></bdo></b><th id='RNBde'></th></span></q></dt></tr></i><div id='RNBde'><tfoot id='RNBde'></tfoot><dl id='RNBde'><fieldset id='RNBde'></fieldset></dl></div>
              • <small id='RNBde'></small><noframes id='RNBde'>

              • <legend id='RNBde'><style id='RNBde'><dir id='RNBde'><q id='RNBde'></q></dir></style></legend>
                  本文介绍了无法在“对象"实例上设置属性班级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  所以,我在回答 时正在玩 Python这个问题,我发现这是无效的:

                  o = object()o.attr = '你好'

                  由于 AttributeError: 'object' object has no attribute 'attr'.但是,对于从对象继承的任何类,它都是有效的:

                  类子(对象):经过s = 子()s.attr = '你好'

                  打印 s.attr 按预期显示hello".为什么会这样?Python 语言规范中有什么规定不能将属性分配给普通对象?

                  解决方案

                  为了支持任意属性赋值,对象需要一个__dict__:一个与对象关联的dict,可以存储任意属性.否则,无处可放置新属性.

                  object 的实例 携带 __dict__ —— 如果确实如此,那么在可怕的循环依赖问题之前(因为 dict,像大多数其他东西一样,继承自 object;-),这将使 Python 中的 每个 对象都带有一个 dict,这意味着开销当前没有或不需要字典的每个对象有 许多 个字节(本质上,所有没有可任意分配属性的对象都没有或不需要字典).

                  例如,使用优秀的 pympler 项目(你可以通过 svn 从 这里),我们可以做一些测量...:

                  >>>从 pympler 导入 asizeof>>>asizeof.asizeof({})144>>>asizeof.asizeof(23)16

                  您不会希望每个 int 占用 144 个字节而不是 16 个字节,对吧?-)

                  现在,当你创建一个类(从任何东西继承)时,事情就会改变......:

                  >>>类 dint(int):通过...>>>asizeof.asizeof(dint(23))184

                  ...现在添加了 __dict__ is (加上,多了一点开销)——所以 dint 实例可以有任意属性,但您为这种灵活性付出了相当大的空间成本.

                  那么,如果你想要 int 只带有 one 额外属性 foobar... 怎么办?这是一种罕见的需求,但 Python 确实为此目的提供了一种特殊的机制......

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

                  ...不像int那么相当,请注意!(甚至是两个 int,一个是 self,一个是 self.foobar - 第二个可以重新分配),但肯定是比 dint 好多了.

                  当类有 __slots__ 特殊属性(字符串序列),然后是 class 语句(更准确地说,默认元类,type) 确实为该类的每个实例配备 __dict__ (因此具有任意属性的能力),只是一组有限的、刚性的槽"(基本上每个地方都可以使用给定的名称保存对某个对象的一个​​引用.

                  作为失去灵活性的交换,您在每个实例中获得了大量字节(只有当您有数以万计的实例在运行时才有意义,但是,用例).p>

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

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

                  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'
                  

                  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?

                  解决方案

                  To support arbitrary attribute assignment, an object needs a __dict__: a dict associated with the object, where arbitrary attributes can be stored. Otherwise, there's nowhere to put new attributes.

                  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).

                  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
                  

                  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.

                  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
                  

                  ...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.

                  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).

                  这篇关于无法在“对象"实例上设置属性班级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:用 beautifulsoup 提取属性值 下一篇:如何知道一个对象是否在 Python 中有一个属性

                  相关文章

                  最新文章

                  <small id='Lfvq5'></small><noframes id='Lfvq5'>

                    <bdo id='Lfvq5'></bdo><ul id='Lfvq5'></ul>
                    <i id='Lfvq5'><tr id='Lfvq5'><dt id='Lfvq5'><q id='Lfvq5'><span id='Lfvq5'><b id='Lfvq5'><form id='Lfvq5'><ins id='Lfvq5'></ins><ul id='Lfvq5'></ul><sub id='Lfvq5'></sub></form><legend id='Lfvq5'></legend><bdo id='Lfvq5'><pre id='Lfvq5'><center id='Lfvq5'></center></pre></bdo></b><th id='Lfvq5'></th></span></q></dt></tr></i><div id='Lfvq5'><tfoot id='Lfvq5'></tfoot><dl id='Lfvq5'><fieldset id='Lfvq5'></fieldset></dl></div>
                  1. <tfoot id='Lfvq5'></tfoot>

                    1. <legend id='Lfvq5'><style id='Lfvq5'><dir id='Lfvq5'><q id='Lfvq5'></q></dir></style></legend>