216 lines
4.9 KiB
Python
216 lines
4.9 KiB
Python
|
class MiClase:
|
||
|
"""Simple clase de ejemplo"""
|
||
|
|
||
|
i = 12345
|
||
|
|
||
|
def f(self):
|
||
|
return 'hola mundo'
|
||
|
|
||
|
x = MiClase()
|
||
|
|
||
|
print(x.__init__())
|
||
|
|
||
|
|
||
|
class Complejo:
|
||
|
def __init__(self, partereal, parteimaginaria):
|
||
|
self.r = partereal
|
||
|
self.i = parteimaginaria
|
||
|
|
||
|
|
||
|
x = Complejo(3.0, -4.5)
|
||
|
print(x.r, x.i)
|
||
|
|
||
|
# Objetos Instancia
|
||
|
|
||
|
x.contador = 1
|
||
|
while x.contador < 10:
|
||
|
x.contador *= 2
|
||
|
print(x.contador)
|
||
|
|
||
|
del x.contador
|
||
|
|
||
|
# Objetos Metodo
|
||
|
|
||
|
x = MiClase()
|
||
|
|
||
|
xf = x.f
|
||
|
|
||
|
cont = 0
|
||
|
while cont < 10:
|
||
|
print(xf())
|
||
|
cont += 1
|
||
|
|
||
|
|
||
|
# Variables de clase y de instancia
|
||
|
|
||
|
class Perro:
|
||
|
tipo = 'canino' # variable de clase compartida por todas las instancias
|
||
|
def __init__(self, nombre):
|
||
|
self.nombre = nombre # variable de instancia única para la instancia
|
||
|
|
||
|
|
||
|
d = Perro('Fido')
|
||
|
e = Perro('Buddy')
|
||
|
|
||
|
print(d.tipo) # compartido por todos los perros 'canino'
|
||
|
|
||
|
print(e.tipo) # compartido por todos los perros 'canino'
|
||
|
|
||
|
print(d.nombre) # único para d 'Fido'
|
||
|
|
||
|
print(e.nombre) # único para e 'Buddy'
|
||
|
|
||
|
|
||
|
# La lista trucos en el siguiente código no debería ser
|
||
|
# usada como variable de clase porque una sola lista sería
|
||
|
# compartida por todos las instancias de Perro:
|
||
|
# INCORRECTO
|
||
|
class Perro:
|
||
|
trucos = [] # uso INCORRECTO de una variable de clase
|
||
|
def __init__(self, nombre):
|
||
|
self.nombre = nombre
|
||
|
|
||
|
def agregar_truco(self, truco):
|
||
|
self.trucos.append(truco)
|
||
|
|
||
|
d = Perro('Fido')
|
||
|
e = Perro('Buddy')
|
||
|
d.agregar_truco('girar')
|
||
|
e.agregar_truco('hacerse el muerto')
|
||
|
d.trucos # compartidos por todos los perros inesperadamente
|
||
|
|
||
|
|
||
|
# DISEÑO CORRECTO
|
||
|
class Perro:
|
||
|
def __init__(self, nombre):
|
||
|
self.nombre = nombre
|
||
|
self.trucos = []
|
||
|
# crea una nueva lista vacía para cada perro
|
||
|
def agregar_truco(self, truco):
|
||
|
self.trucos.append(truco)
|
||
|
|
||
|
d = Perro('Fido')
|
||
|
e = Perro('Buddy')
|
||
|
d.agregar_truco('girar')
|
||
|
e.agregar_truco('hacerse el muerto')
|
||
|
print(d.trucos) # ['girar']
|
||
|
print(e.trucos) # ['hacerse el muerto']
|
||
|
|
||
|
|
||
|
# Función definida fuera de la clase
|
||
|
# algo confuso
|
||
|
|
||
|
def f1(self, x, y):
|
||
|
return min(x, x+y)
|
||
|
|
||
|
class C:
|
||
|
f = f1
|
||
|
def g(self):
|
||
|
return 'hola mundo'
|
||
|
|
||
|
h = g
|
||
|
|
||
|
# Los métodos pueden llamar a otros métodos de la instancia usando el argumento self
|
||
|
class Bolsa:
|
||
|
def __init__(self):
|
||
|
self.datos = []
|
||
|
|
||
|
def agregar(self, x):
|
||
|
self.datos.append(x)
|
||
|
|
||
|
def dobleagregar(self, x):
|
||
|
self.agregar(x)
|
||
|
self.agregar(x)
|
||
|
|
||
|
"""
|
||
|
Todo valor es un objeto, y por lo tanto tiene una clase
|
||
|
(también llamado su tipo). Ésta se almacena como objeto.__class__.
|
||
|
|
||
|
|
||
|
# HERENCIA
|
||
|
class ClaseDerivada(modulo.ClaseBase):
|
||
|
|
||
|
# Python tiene dos funciones integradas que funcionan con herencia
|
||
|
# isinstance(obj, int) # ejm
|
||
|
|
||
|
issubclass(float, int)
|
||
|
|
||
|
# HERENCIA MULTIPLE
|
||
|
class ClaseDerivada(Base1, Base2, Base3):
|
||
|
|
||
|
|
||
|
# mas en:
|
||
|
# https://www.python.org/download/releases/2.3/mro/
|
||
|
"""
|
||
|
|
||
|
# Variables privadas
|
||
|
class Mapeo:
|
||
|
def __init__(self, iterable):
|
||
|
self.lista_de_items = []
|
||
|
self.__actualizar(iterable)
|
||
|
|
||
|
def actualizar(self, iterable):
|
||
|
for item in iterable:
|
||
|
self.lista_de_items.append(item)
|
||
|
|
||
|
__actualizar = actualizar # copia privada del actualizar() original
|
||
|
|
||
|
|
||
|
class SubClaseMapeo(Mapeo):
|
||
|
def actualizar(self, keys, values): # provee una nueva signatura para actualizar()
|
||
|
for item in zip(keys, values): # pero no rompe __init__()
|
||
|
self.lista_de_items.append(item)
|
||
|
|
||
|
|
||
|
# Cambalache
|
||
|
|
||
|
class Empleado:
|
||
|
pass
|
||
|
|
||
|
juan = Empleado() # Crear un registro de empleado vacío
|
||
|
|
||
|
juan.nombre = 'Juan Flores' # Llenar los campos del registro
|
||
|
juan.depto = 'lab. de computación'
|
||
|
juan.salario = 1000
|
||
|
"""
|
||
|
Algún código Python que espera un tipo abstracto de datos en particular puede frecuentemente recibir en cambio una clase
|
||
|
que emula los métodos de aquel tipo de datos. Por ejemplo, si tenés una función que formatea algunos datos a partir de un
|
||
|
objeto archivo, podés definir una clase con métodos read() y readline() que obtengan los datos de alguna cadena en
|
||
|
memoria intermedia, y pasarlo como argumento.
|
||
|
Los objetos método de instancia tienen atributos también: m.__self__ es el objeto instancia con el método m() , y
|
||
|
m.__func__ es el objeto función correspondiente al método.
|
||
|
|
||
|
|
||
|
|
||
|
Ambitos y espacios de variables (alcance de variables)
|
||
|
|
||
|
"""
|
||
|
def prueba_ambitos():
|
||
|
|
||
|
def hacer_local():
|
||
|
algo = "algo local"
|
||
|
|
||
|
|
||
|
def hacer_nonlocal():
|
||
|
nonlocal algo
|
||
|
algo = "algo no local"
|
||
|
|
||
|
|
||
|
def hacer_global():
|
||
|
global algo
|
||
|
algo = "algo global"
|
||
|
|
||
|
algo = "algo de prueba"
|
||
|
hacer_local()
|
||
|
print("Luego de la asignación local:", algo)
|
||
|
|
||
|
hacer_nonlocal()
|
||
|
print("Luego de la asignación no local:", algo)
|
||
|
|
||
|
hacer_global()
|
||
|
print("Luego de la asignación global:", algo)
|
||
|
|
||
|
prueba_ambitos()
|
||
|
print("In global scope:", algo)
|
||
|
|