Introducción
Esta sección introduce la declaración de clase y la idea de crear nuevos objetos.
This tutorial is from open-source community. Access the source code
💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí
Esta sección introduce la declaración de clase y la idea de crear nuevos objetos.
Una técnica de programación en la que el código se organiza como una colección de objetos.
Un objeto consta de:
Ya has estado usando algo de POO durante este curso.
Por ejemplo, manipular una lista.
>>> nums = [1, 2, 3]
>>> nums.append(4) ## Método
>>> nums.insert(1,10) ## Método
>>> nums
[1, 10, 2, 3, 4] ## Datos
>>>
nums
es una instancia de una lista.
Los métodos (append()
e insert()
) están adjuntos a la instancia (nums
).
class
Utiliza la declaración class
para definir un nuevo objeto.
class Player:
def __init__(self, x, y):
self.x = x
self.y = y
self.health = 100
def move(self, dx, dy):
self.x += dx
self.y += dy
def damage(self, pts):
self.health -= pts
En resumen, una clase es un conjunto de funciones que realizan diversas operaciones sobre los llamados instancias.
Las instancias son los verdaderos objetos que manipulas en tu programa.
Se crean llamando a la clase como si fuera una función.
>>> a = Player(2, 3)
>>> b = Player(10, 20)
>>>
a
y b
son instancias de Player
.
Enfatiza: La declaración de clase es solo una definición (no hace nada por sí misma). Similar a la definición de una función.
Cada instancia tiene sus propios datos locales.
>>> a.x
2
>>> b.x
10
Estos datos se inicializan por el método __init__()
.
class Player:
def __init__(self, x, y):
## Cualquier valor almacenado en `self` es datos de instancia
self.x = x
self.y = y
self.health = 100
No hay restricciones sobre el número total o el tipo de atributos almacenados.
Los métodos de instancia son funciones aplicadas a las instancias de un objeto.
class Player:
...
## `move` es un método
def move(self, dx, dy):
self.x += dx
self.y += dy
El objeto mismo siempre se pasa como primer argumento.
>>> a.move(1, 2)
## hace coincidir `a` con `self`
## hace coincidir `1` con `dx`
## hace coincidir `2` con `dy`
def move(self, dx, dy):
Por convención, la instancia se llama self
. Sin embargo, el nombre real utilizado no es importante. El objeto siempre se pasa como primer argumento. Es simplemente un estilo de programación de Python llamar a este argumento self
.
Las clases no definen un ámbito de nombres.
class Player:
...
def move(self, dx, dy):
self.x += dx
self.y += dy
def left(self, amt):
move(-amt, 0) ## NO. Llama a una función global `move`
self.move(-amt, 0) ## SI. Llama al método `move` de arriba.
Si quieres operar sobre una instancia, siempre la referenciar explícitamente (por ejemplo, self
).
A partir de este conjunto de ejercicios, comenzamos a realizar una serie de cambios en el código existente de secciones anteriores. Es fundamental que tengas una versión funcional del Ejercicio 3.18 para comenzar. Si no la tienes, por favor trabaja a partir del código de solución que se encuentra en el directorio Solutions/3_18
. Está bien copiarlo.
En las secciones 2 y 3, trabajamos con datos representados como tuplas y diccionarios. Por ejemplo, una posesión de acciones podría representarse como una tupla así:
s = ('GOOG',100,490.10)
o como un diccionario así:
s = { 'name' : 'GOOG',
'shares' : 100,
'price' : 490.10
}
Incluso puedes escribir funciones para manipular estos datos. Por ejemplo:
def cost(s):
return s['shares'] * s['price']
Sin embargo, a medida que tu programa crece, es posible que desees crear una mejor sensación de organización. Por lo tanto, otra forma de representar datos sería definir una clase. Crea un archivo llamado stock.py
y define una clase Stock
que represente una sola posesión de acciones. Haz que las instancias de Stock
tengan atributos name
, shares
y price
. Por ejemplo:
>>> import stock
>>> a = stock.Stock('GOOG',100,490.10)
>>> a.name
'GOOG'
>>> a.shares
100
>>> a.price
490.1
>>>
Crea algunos más objetos Stock
y manipúlalos. Por ejemplo:
>>> b = stock.Stock('AAPL', 50, 122.34)
>>> c = stock.Stock('IBM', 75, 91.75)
>>> b.shares * b.price
6117.0
>>> c.shares * c.price
6881.25
>>> stocks = [a, b, c]
>>> stocks
[<stock.Stock object at 0x37d0b0>, <stock.Stock object at 0x37d110>, <stock.Stock object at 0x37d050>]
>>> for s in stocks:
print(f'{s.name:>10s} {s.shares:>10d} {s.price:>10.2f}')
... mira la salida...
>>>
Una cosa que hay que enfatizar aquí es que la clase Stock
actúa como una fábrica para crear instancias de objetos. Básicamente, la llamas como si fuera una función y te crea un nuevo objeto. Además, hay que enfatizar que cada objeto es distinto: cada uno tiene sus propios datos que son separados de otros objetos que se hayan creado.
Un objeto definido por una clase es algo similar a un diccionario, solo con una sintaxis un poco diferente. Por ejemplo, en lugar de escribir s['name']
o s['price']
, ahora se escribe s.name
y s.price
.
Con las clases, puedes adjuntar funciones a tus objetos. Estas se conocen como métodos y son funciones que operan sobre los datos almacenados dentro de un objeto. Agrega un método cost()
y sell()
a tu objeto Stock
. Deberían funcionar así:
>>> import stock
>>> s = stock.Stock('GOOG', 100, 490.10)
>>> s.cost()
49010.0
>>> s.shares
100
>>> s.sell(25)
>>> s.shares
75
>>> s.cost()
36757.5
>>>
Intenta estos pasos para crear una lista de instancias de Stock a partir de una lista de diccionarios. Luego, calcula el costo total:
>>> import fileparse
>>> with open('portfolio.csv') as lines:
... portdicts = fileparse.parse_csv(lines, select=['name','shares','price'], types=[str,int,float])
...
>>> portfolio = [ stock.Stock(d['name'], d['shares'], d['price']) for d in portdicts]
>>> portfolio
[<stock.Stock object at 0x10c9e2128>, <stock.Stock object at 0x10c9e2048>, <stock.Stock object at 0x10c9e2080>,
<stock.Stock object at 0x10c9e25f8>, <stock.Stock object at 0x10c9e2630>, <stock.Stock object at 0x10ca6f748>,
<stock.Stock object at 0x10ca6f7b8>]
>>> sum([s.cost() for s in portfolio])
44671.15
>>>
Modifica la función read_portfolio()
en el programa report.py
de modo que lea una cartera en una lista de instancias de Stock
como se mostró en el Ejercicio 4.3. Una vez que hayas hecho eso, corrige todo el código en report.py
y pcost.py
para que funcione con instancias de Stock
en lugar de diccionarios.
Pista: No deberías tener que hacer cambios importantes en el código. Principalmente estarás cambiando el acceso a los diccionarios como s['shares']
a s.shares
.
Deberías poder ejecutar tus funciones como antes:
>>> import pcost
>>> pcost.portfolio_cost('portfolio.csv')
44671.15
>>> import report
>>> report.portfolio_report('portfolio.csv', 'prices.csv')
Name Shares Price Change
---------- ---------- ---------- ----------
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84
>>>
¡Felicitaciones! Has completado el laboratorio de Clases. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.