Wann, wo und wie kann ich die __CLASS__ attr eines Objekts ändern?
-
26-09-2019 - |
Frage
Ich möchte in der Lage sein zu tun:
>>> 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
Lösung
habe ich es auf diese Weise gelöst:
>>> 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'>
Andere Tipps
Python 2 verfügt nicht über eine einheitliche Objekthierarchie (dh. Nicht alles von der Objektklasse abstammen). Alles, was Teil dieser Hierarchie ist mit über __class__
gespielt werden, aber diejenigen, die nicht sind, können auf diese Weise nicht geändert werden (oder überhaupt, wirklich). Diese sind Pythons „Typen“ genannt, und sie sind hart codiert in C Beispiele für Typen sind str
, int
, float
, list
, tuple
usw. Dies bedeutet, dass Sie nicht Typen auf die gleiche Weise wie Klassen verwenden können, beispielsweise Sie können nicht die Klasse von einer Instanz einer Art ändern, können Sie nicht, zu entfernen oder modifizieren Methoden der Arten, usw. die folgenden Transkript zeigen den Unterschied im Verhalten zwischen Typen wie str
(hart codierte, nicht-dynamische C-Konstrukte) hinzufügen und Klassen ich habe genannt A und B (veränderbar, dynamisch, Python-Konstrukte):
>>> 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
Nur Klassen, die mit einem class
Schlüsselwort definiert wurden für __class__
Attribut Zuordnung verwendet werden könnten:
>>> class C:
pass
>>> class D:
pass
>>> C().__class__ = D
>>>
habe ich versucht, auf diese Weise!
>>> class C(str):
... __class__ = str
...
>>> c = C()
>>> c.__class__
<class 'str'>