2012-04-11 11 views
7

Cada clase en python hereda de la clase 'objeto'. Me pregunto sobre el mecanismo interno de la implementación de la clase 'objeto'. ¿Por qué no se le puede asignar ningún atributo de usuario a la clase 'objeto'? Estoy convencido de que está relacionado con la administración de la memoria, pero ¿qué ocurre si el usuario piensa en implementar él mismo la administración de la memoria, por qué no puede anular la clase 'objeto' en Python? Esto se basa en mi interés y quiero saber sobre qué podría no tener ninguna aplicación programática, pero sería bueno conocer la característica interna del idioma en sí.por qué la clase 'objeto' no tiene atributos de conjunto de usuario

+2

En realidad, en Python 2.x, solo las clases de nuevo estilo heredan de '' object''. (Bueno, y en Python 3.x, pero todas las clases son de estilo nuevo, así que no tiene sentido mencionarlo). –

+1

No es una gran razón para un voto negativo, pero es un gran lugar para una respuesta para educar al preguntador ... me parece una pregunta bien pensada y válida. +1 – ImGreg

+1

Jack, ¿puedes aclarar si estás hablando de agregar atributos a la clase de objeto o a instancias de esa clase? –

Respuesta

1

Si tuviera que derivar el razonamiento a partir de primeros principios, yo podría pensar en ello en términos del mecanismo de __slots__. Algunos tipos de clases solo necesitan una pequeña cantidad de atributos, y el conjunto de atributos siempre se fija para cada instancia, por lo que la flexibilidad de una capacidad de atributos de usuario "dict" sería un despilfarro de la CPU (buscando atributos denominados dinámicamente) y espacio (la sobrecarga de un dict vacío, pequeño pero distinto de cero), que realmente puede sumar una gran cantidad de gastos generales si hay un gran número de instancias.

por supuesto, este es exactamente el problema que resuelve el mecanismo __slots__. el espacio se asigna al objeto para los atributos definidos en las ranuras. si hay un atributo __dict__, los atributos que no son de ranura se pueden encontrar allí, y si no hay ningún atributo __dict__, no obtiene los atributos dinámicos ni el costo del objeto dict innecesario (que es un objeto de montón adicional distinto de la instancia en sí).

cuanto a por qué object en sí no tiene una ranura para __dict__, así, incluso si una subclase indicó que no lo hicieron necesidad la ranura __dict__, si heredan de una clase que hace , a continuación, la instancia todavía debe tener un __dict__; si object tuviera un __dict__, entonces cada clase también pagaría el precio de tener un __dict__, incluso si no lo necesitaban.

En cambio; las subclases obtienen __dict__ (y __weakref__, por razones análogas) a menos que ellos mismos definan un atributo de clase __slots__.

¿Y por qué necesitaría una instancia simple de object en absoluto? ¿Solo necesitas una bolsa de atributos? bien, entonces usa un dict. Si realmente necesitas un objeto de algún tipo con comportamientos y atributos, entonces estás creando una subclase de todos modos.

Sobre la única razón que puedo imaginar usando object() en vez de una subclase de object, es cuando la única característica de la instancia que es de interés es su identidad. Esto vendría cuando una función toma argumentos, y para el cual None o algún otro valor centinela obvia debe entenderse como algo distinto del predeterminado:

BAR_DEFAULT = object() 
def foo(bar=BAR_DEFAULT): 
    if bar is BAR_DEFAULT: 
     #... 

En este caso usted no necesita ni particularmente desea atributos en la instancia de object,

3

Los tipos definidos en C nunca pueden tener atributos asignados por el usuario. Si desea reemplazar object globalmente, necesitará iterar sobre cada una de las clases existentes, luego reemplace __builtin__.object para capturar toda la creación futura de clases. E incluso eso no es confiable ya que el viejo objeto podría estar ligado a otro lugar.

3

Esto se ha discutido en StackOverflow, pero me cuesta encontrar la discusión para vincularlo.

La razón por la que preguntaba es porque quería simplificar este ejemplo:

class Box(object): 
    pass 

box = Box() 
box.a = "some value" 
box.b = 42 

Aquí estoy usando box como una especie de diccionario, uno donde las claves sólo pueden ser identificadores. Lo hago porque es más conveniente escribir box.a que box["a"].

que quería hacer esto:

box = object() 
box.a = "some value" # doesn't work 

La razón es que object es la raíz de todos los objetos en Python. Cualquier atributo que tenga object debe ser de cualquier tipo derivado. Si desea hacer una lista grande que contenga una gran cantidad de objetos, quiere que sean lo más pequeños posible para que no se quede sin memoria. Entonces object es mínimo.

EDIT: He encontrado el enlace que estaba tratando de recordar:

struct objects in python

Cuestiones relacionadas