'''
Tipo: Concepto, Ejercicio, Pregunta...
Fuente: libro, curso, ...


Este chunk tiene como propósito revisar cocneptos fundamentales.

Variable de isntancia

Variable de clase
Una diferencia importante entre clase e instancia e sla forma de usarse, están fuera del constructor __init__()


Método de Instancias
Método de Clase


Método de Estpatico:
Se prefeire e a veces métodos estáticos, la funcioanldiad está estrechamente relacioanda con la clase, se cumple principio de abstracción.


Método especiales:

__init__():


Los dunder methods.


'''


class Persona():

    # Variable de clase
    edad = 18


    # Sirve para personalzia la creación de las instancias de las clases.
    # Podemos trabajr los inmutables
    # New no necesita self, sino uan referencia a la clase que lo invoca, es un método estático que devuele un objeto.

    # En teoria va primero, se ejecuta primero. El es el que realmente cra la clase  y lo mandar a incialziar
    def __new__(cls, nombre, nacionalidad):
        print("New class")
        # __new__ debe regresar un objeto. Se usa super para regresar una instancia
        # Si no se retorna nada, la instancia no se inicialzia.
        return super().__new__(cls)

    # Constructor, inicializa
    def __init__(self, nombre, nacionalidad):
        print("Ininitialization of the instance")
        self.nombre = nombre
        self.nacionalidad = nacionalidad

    

    # Método de instancia requiere de la variable self.
    def nadar(self):
        print("Nada de nada")
    

    # Método de clase no posee la variable self. Pero si la variable "cls"
    # Un método de clase solo funciona con una directiva espcial llamada classsmethod.
    # Existen diferenters decoradores. Este nos permite no crear un objeto usarse sin instanciar

    @classmethod
    def saludar(cls, nombre):
        print("Hola "+nombre)

    # Método estático
    # No requiere de ningún argumento y se usa el decorador staticmethod

    @staticmethod
    def brincar():
        print("Brincar<!!!")



# El área de un círculo puede ser una propiedad no necesariamente un método
# Es decir peudo expresarlo como un método de instancia, clase, estático, variable.
# Lo correcto será como una propiedad.

class Circulo():

    def __init__(self, radio):
        self.radio = radio


    # Para declarar propeidades usamos el decorador @property
    # Nos va a permitir acceder a una propiedad de un objeto creado en python.  objeto.propiedad
    @property
    def area(self):
        return 3.1416*(self.radio**2)













# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# La variable de isntancia de instancia son las precedidas del nombre de self.variable_instancia
stuff = Persona("José", "México")


print(stuff.edad) #18. No necesita crear una nstancia para poder acceder a este.
# print(Persona.nombre) #Arroha error, debido a que no está inicialziado el objeto.


#Método de clase. 
Persona.saludar("Pepe")


# Método Estático
stuff.brincar()


# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
circle = Circulo(10) # 314.15999999999997

# se invoca como una propeidad del objeto instanciado.
print(circle.area)
'''
Tipo: Concepto, Ejercicio, Pregunta...
Fuente: libro, curso, ...


Este chunk tiene como propósito revisar cocneptos fundamentales.

Variable de isntancia

Variable de clase
Una diferencia importante entre clase e instancia e sla forma de usarse, están fuera del constructor __init__()


Método de Instancias
Método de Clase


Método de Estpatico:
Se prefeire e a veces métodos estáticos, la funcioanldiad está estrechamente relacioanda con la clase, se cumple principio de abstracción.


Método especiales:

__init__():


Los dunder methods.


'''


class Persona():

    # Variable de clase
    edad = 18


    # Sirve para personalzia la creación de las instancias de las clases.
    # Podemos trabajr los inmutables
    # New no necesita self, sino uan referencia a la clase que lo invoca, es un método estático que devuele un objeto.

    # En teoria va primero, se ejecuta primero. El es el que realmente cra la clase  y lo mandar a incialziar
    def __new__(cls, nombre, nacionalidad):
        print("New class")
        # __new__ debe regresar un objeto. Se usa super para regresar una instancia
        # Si no se retorna nada, la instancia no se inicialzia.
        return super().__new__(cls)

    # Constructor, inicializa
    def __init__(self, nombre, nacionalidad):
        print("Ininitialization of the instance")
        self.nombre = nombre
        self.nacionalidad = nacionalidad

    

    # Método de instancia requiere de la variable self.
    def nadar(self):
        print("Nada de nada")
    

    # Método de clase no posee la variable self. Pero si la variable "cls"
    # Un método de clase solo funciona con una directiva espcial llamada classsmethod.
    # Existen diferenters decoradores. Este nos permite no crear un objeto usarse sin instanciar

    @classmethod
    def saludar(cls, nombre):
        print("Hola "+nombre)

    # Método estático
    # No requiere de ningún argumento y se usa el decorador staticmethod

    @staticmethod
    def brincar():
        print("Brincar<!!!")



# El área de un círculo puede ser una propiedad no necesariamente un método
# Es decir peudo expresarlo como un método de instancia, clase, estático, variable.
# Lo correcto será como una propiedad.

class Circulo():

    def __init__(self, radio):
        self.radio = radio


    # Para declarar propeidades usamos el decorador @property
    # Nos va a permitir acceder a una propiedad de un objeto creado en python.  objeto.propiedad
    @property
    def area(self):
        return 3.1416*(self.radio**2)













# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# La variable de isntancia de instancia son las precedidas del nombre de self.variable_instancia
stuff = Persona("José", "México")


print(stuff.edad) #18. No necesita crear una nstancia para poder acceder a este.
# print(Persona.nombre) #Arroha error, debido a que no está inicialziado el objeto.


#Método de clase. 
Persona.saludar("Pepe")


# Método Estático
stuff.brincar()


# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
circle = Circulo(10) # 314.15999999999997

# se invoca como una propeidad del objeto instanciado.
print(circle.area)
Tipo: Concepto, Ejercicio, Pregunta... Fuente: libro, curso, ...   Este chunk tiene como propósito revisar cocneptos fundamentales.  Variable de isntancia  Variable de clase Una diferencia importante entre clase e instancia e sla forma de usarse, están fuera del constructor __init__()   Método de Instancias Método de Clase   Método de Estpatico: Se prefeire e a veces métodos estáticos, la funcioanldiad está estrechamente relacioanda con la clase, se cumple principio de abstracción.   Método especiales:  __init__():   Los dunder methods. # Variable de clase # Sirve para personalzia la creación de las instancias de las clases. # Podemos trabajr los inmutables # New no necesita self, sino uan referencia a la clase que lo invoca, es un método estático que devuele un objeto. # En teoria va primero, se ejecuta primero. El es el que realmente cra la clase  y lo mandar a incialziar # __new__ debe regresar un objeto. Se usa super para regresar una instancia # Si no se retorna nada, la instancia no se inicialzia. # Constructor, inicializa # Método de instancia requiere de la variable self. # Método de clase no posee la variable self. Pero si la variable "cls" # Un método de clase solo funciona con una directiva espcial llamada classsmethod. # Existen diferenters decoradores. Este nos permite no crear un objeto usarse sin instanciar # Método estático # No requiere de ningún argumento y se usa el decorador staticmethod # El área de un círculo puede ser una propiedad no necesariamente un método # Es decir peudo expresarlo como un método de instancia, clase, estático, variable. # Lo correcto será como una propiedad. # Para declarar propeidades usamos el decorador @property # Nos va a permitir acceder a una propiedad de un objeto creado en python.  objeto.propiedad # ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ # La variable de isntancia de instancia son las precedidas del nombre de self.variable_instancia #18. No necesita crear una nstancia para poder acceder a este. # print(Persona.nombre) #Arroha error, debido a que no está inicialziado el objeto. #Método de clase. # Método Estático # ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ # 314.15999999999997 # se invoca como una propeidad del objeto instanciado.