El atributo de la clase python no está en __init__

Quiero saber por qué funcionan los siguientes códigos?

#!/usr/bin/env python3 import sys class Car(): def __init__(self): pass if __name__ == '__main__': c = Car() c.speed = 3 c.time = 5 print(c.speed, c.time) 

Encontré accidentalmente que no tengo que iniciar atributos en init . Aprendo de cada tutor que tengo que poner asignación en init como abajo.

 #!/usr/bin/env python3 import sys class Car(): def __init__(self): self.speed = 3 self.time = 5 if __name__ == '__main__': c = Car() print(c.speed, c.time) 

Si hay algunos documentos oficiales que puedan explicar esto sería mejor.

Es atributos de clase vs atributos de instancia vs atributos dynamics. Cuando tu lo hagas:

 class Car(): def __init__(self): pass c = Car() c.speed = 3 c.time = 5 

speed y el time son atributos dynamics (no estoy seguro si este es un término oficial) . Si el uso de la clase es tal que estos atributos se establecen antes de llamar a cualquier otro método de Car , entonces esos métodos pueden usar self.speed . De lo contrario, obtendrá un error:

 >>> d = Car() >>> d.speed Traceback (most recent call last): File "", line 1, in  AttributeError: 'Car' object has no attribute 'speed' >>> 

Esto sucede porque para c , la velocidad y el tiempo son atributos en esa instancia de Car . Su existencia o valor no se propaga a través de otras instancias de Car. Entonces cuando creo d y luego trato de buscar d.speed , el atributo no existe. Como ha dicho en su propio comentario, “surgen cuando se asignan por primera vez”.

Encontré accidentalmente que no tengo que iniciar atributos en init. Aprendo de cada tutor que tengo que poner asignación en init como abajo.

Tus tutores estaban muy equivocados o no entendiste lo que querían decir. En el ejemplo que dio, cada Coche tiene la misma speed y time iniciales. Normalmente, un __init__ se vería así:

 class Car(): def __init__(self, speed, time): # notice that speed and time are # passed as arguments to init self.speed = speed self.time = time 

Luego puede inicializar un Car con: c = Car(3, 5) . O ponga valores predeterminados en init si es opcional.

Edición: ejemplo adaptado de la documentación :

 class Dog: kind = 'canine' # class variable shared by all instances def __init__(self, name): self.name = name # instance variable unique to each instance >>> d = Dog('Fido') >>> e = Dog('Buddy') >>> d.kind # shared by all dogs 'canine' >>> e.kind # shared by all dogs 'canine' >>> d.name # unique to d 'Fido' >>> e.name # unique to e 'Buddy' >>> d.age = 3 # dynamic attribute/variable, unique to d >>> d.age 3 >>> e.age # e doesn't have it at all Traceback (most recent call last): File "", line 1, in  AttributeError: 'Dog' object has no attribute 'age'