Pregunta

Me gustaría ser capaz de hacer:

>>> 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
¿Fue útil?

Solución

He resuelto de esta manera:

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

Otros consejos

Python 2 no tiene una jerarquía de objetos unificado (es decir. No todo es descendiente de la clase de objeto). Cualquier cosa que es parte de esta jerarquía se puede jugar con vía __class__, pero los que no lo son no se puede modificar de esta manera (o en absoluto, en realidad). Estos se llaman "tipos" de Python, y son no modificable en C. Ejemplos de tipos son str, int, float, list, tuple, etc. Esto significa que no se puede utilizar tipos de la misma manera como las clases, por ejemplo, no se puede cambiar la clase de una instancia de un tipo, no se puede añadir, eliminar o modificar los métodos de los tipos, etc. los siguientes transcripción muestra la diferencia de comportamiento entre los tipos tales como str (no modificable, construcciones C no dinámicos) y clases que he llamado A y B (cambiante, dinámico, construcciones de 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

Sólo las clases que se definieron con una palabra clave class podrían ser utilizados para la asignación de atributos __class__:

>>> class C:
    pass

>>> class D:
    pass

>>> C().__class__ = D
>>>

Me trató de esta manera!

>>> class C(str):
...     __class__ = str
...
>>> c = C()
>>> c.__class__
<class 'str'>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top