我什么时候在哪里以及如何更改对象的 __class__ 属性?
-
26-09-2019 - |
题
我希望能够做到:
>>> 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
解决方案
我已经解决了它这种方式:
>>> 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'>
其他提示
Python 2 没有统一的对象层次结构(即。并非所有东西都是对象类的后代)。该层次结构中的任何内容都可以通过以下方式进行播放 __class__
, ,但那些不是的不能以这种方式修改(或者根本不能修改)。这些被称为 Python 的“类型”,并且用 C 进行硬编码。类型的示例有 str
, int
, float
, list
, tuple
, , ETC。这意味着您不能以与类相同的方式使用类型,例如您不能更改类型实例的类,不能添加、删除或修改类型的方法等。以下文字记录显示了不同类型之间的行为差异,例如 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
可用于class
属性分配只有具有__class__
关键字中定义的类:
>>> class C:
pass
>>> class D:
pass
>>> C().__class__ = D
>>>
我试过这样!
>>> class C(str):
... __class__ = str
...
>>> c = C()
>>> c.__class__
<class 'str'>
不隶属于 StackOverflow