2010-01-31 16 views
23
>>> class BOOL(bool): 
...  print "why?" 
... 
why? 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: Error when calling the metaclass bases 
    type 'bool' is not an acceptable base type 

Pensé que Python confiaba en el programador.¿Por qué no puedo extender bool en Python?

+10

¿Desea agregar un valor FileNotFound? – Juliano

+1

Una búsqueda de Google o una búsqueda SO para "composición vs. herencia" podría ser útil aquí. – MatrixFrog

Respuesta

41

toma de Guido en él:

I thought about this last night, and realized that you shouldn't be allowed to subclass bool at all! A subclass would only be useful when it has instances, but the mere existance of an instance of a subclass of bool would break the invariant that True and False are the only instances of bool! (An instance of a subclass of C is also an instance of C.) I think it's important not to provide a backdoor to create additional bool instances, so I think bool should not be subclassable.

Referencia: http://mail.python.org/pipermail/python-dev/2002-March/020822.html

+14

True y False son singleton. Esta es una mejor respuesta. –

+1

Es bueno saber que las cosas son consistentes: 'clase Foo (Ninguna .__ clase__): ...' -> 'TypeError: tipo 'NoneType' no es un tipo de base aceptable' –

4

Porque se supone que bool solo tiene dos valores: True y False. Si fue capaz de crear la subclase bool, podría definir un número arbitrario de valores para ella, y eso definitivamente no es lo que quiere que suceda.

Una mejor pregunta es: ¿por qué quieres extender bool?

+0

Me gustaría agregar un atributo que me permita rastrear algunas cosas en el objeto. –

+4

@Juanjo, entonces lo que quieres no es un booleano, es una tupla de un booleano y algo más. Un booleano debe ser True o False, no hay otros valores ni ningún otro atributo que haga que una instancia de esa clase se compare negativamente con True y False.Eso sucedería, ya no sería booleano. – Juliano

+0

Está bien, pero no puedo anular int .__ nonzero__ para devolver esta tupla. ¿Puedo? –

5

Si está utilizando Python 3, y que desea tener una clase que puede ser evaluada como un valor lógico, pero también contienen otras funcionalidades , implemente __bool__ en su clase.

En Python 2 se puede lograr el mismo efecto implementando __nonzero__ o __len__ (si su clase es un contenedor).

+3

En Python 2.x puede hacer lo mismo implementando '__nonzero__' o' __len__'. –

+0

Quiero 1 y 2 para devolver una instancia de mi clase. ¿Como lo harias? –

+2

Primero subclassing bool, luego anulando los métodos int ... ¿por qué no haces tu propia clase desde cero? – Agos

9

Desde el PO menciona en un comentario:

I want 1 and 2 to return an instance of my class.

creo que es importante señalar que esto es totalmente imposible: Python no le permite alterar tipos integrados (y, especialmente, sus métodos especiales). Literal 1 siempre habrá una instancia de tipo incorporado int, y en todo caso la semántica fundamentales del titular and no son reemplazable de todos modos - a and b es siempre idéntica a b if a else a para cualquier a y b (sin coacción bool involucrado, a pesar de que el OP parece creer erróneamente que uno está sucediendo).

Repitiendo este punto crucial: el valor de a and b es siempre, inalterablemente ya sea a o b - no hay ninguna manera de romper esta restricción semántica (incluso si a y b eran ejemplos de sus propias clases particulares - - aún menos, por supuesto, cuando están obligados a ser instancias de Python incorporado en int! -).

Cuestiones relacionadas