【问题标题】:When where and how can i change the __class__ attr of an object?何时以及如何更改对象的 __class__ 属性?
【发布时间】:2011-03-02 02:15:36
【问题描述】:

我希望能够做到:

>>> class a(str):
...     pass
...
>>> b = a()
>>> b.__class__ = str
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __class__ assignment: only for heap types

【问题讨论】:

  • 我想说这是来自解释器的一个相当糟糕的信息,因为“堆类型”这个术语对于大多数 Python 程序员来说并不熟悉,而且似乎没有任何方法在 Python 3 中创建一个类,其实例具有可分配的 class。或者至少我还没有找到。
  • 不错的一个。我的意思是,当然,一个可分配的__class__ 属性。

标签: python python-datamodel


【解决方案1】:

我是这样解决的:

>>> class C(str):
...     def __getattribute__(self, name):
...         if name == '__class__':
...             return str
...         else:
...             return super(C, self).__getattribute__(name)
...         
>>> c = C()
>>> c.__class__
<type 'str'>

【讨论】:

    【解决方案2】:

    Python 2 没有统一的对象层次结构(即,并非所有内容都来自对象类)。属于这个层次结构的任何东西都可以通过__class__ 播放,但不能以这种方式修改(或者根本不可以修改)。这些被称为 Python 的“类型”,它们在 C 中被硬编码。类型的示例有 strintfloatlisttuple 等。这意味着您不能使用类型与类相同,例如不能更改类型实例的类,不能添加、删除或修改类型的方法等。以下记录显示了类型之间的行为差​​异,例如str (硬编码、非动态 C 构造)和我称为 A 和 B 的类(可变、动态、Python 构造):

    >>> str
    <type 'str'>
    >>> class A:
    ...     pass
    ... 
    >>> a = A()
    >>> A
    <class __main__.A at 0xb747f2cc>
    >>> a
    <__main__.A instance at 0xb747e74c>
    >>> type(a)
    <type 'instance'>
    >>> type(A)
    <type 'classobj'>
    >>> type(str)
    <type 'type'>
    >>> type(type(a))
    <type 'type'>
    >>> type(type(A))
    <type 'type'>
    >>> A.foo = lambda self,x: x
    >>> a.foo(10)
    10
    >>> A().foo(5)
    5
    >>> str.foo = lambda self,x: x
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can't set attributes of built-in/extension type 'str'
    >>> 'abc'.foo(5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'str' object has no attribute 'foo'
    >>> class B:
    ...     pass
    ... 
    >>> a.__class__
    <class __main__.A at 0xb747f2cc>
    >>> a.__class__ = B
    >>> a
    <__main__.B instance at 0xb747e74c>
    >>> 'abc'.__class__
    <type 'str'>
    >>> 'abc'.__class__ = B
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: __class__ must be set to new-style class, not 'classobj' object
    >>> class B(object):
    ...     pass
    ... 
    >>> 'abc'.__class__ = B
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: __class__ assignment: only for heap types
    

    【讨论】:

    • python 2 中的一切都是对象实例。
    • 你的意思是不是所有的类都是类型的实例。
    【解决方案3】:

    只有使用class 关键字定义的类才能用于__class__ 属性分配:

    >>> class C:
        pass
    
    >>> class D:
        pass
    
    >>> C().__class__ = D
    >>>
    

    【讨论】:

    【解决方案4】:

    我试过这个方法!

    >>> class C(str):
    ...     __class__ = str
    ...
    >>> c = C()
    >>> c.__class__
    <class 'str'>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2019-03-09
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多