Introdução
Esta seção introduz a declaração de classe (class statement) e a ideia de criar novos objetos.
This tutorial is from open-source community. Access the source code
Esta seção introduz a declaração de classe (class statement) e a ideia de criar novos objetos.
Uma técnica de programação onde o código é organizado como uma coleção de objetos.
Um objeto consiste em:
Você já utilizou alguma POO durante este curso.
Por exemplo, ao manipular uma lista.
>>> nums = [1, 2, 3]
>>> nums.append(4) ## Method
>>> nums.insert(1,10) ## Method
>>> nums
[1, 10, 2, 3, 4] ## Data
>>>
nums é uma instância de uma lista.
Os métodos (append() e insert()) estão anexados à instância (nums).
classUse a declaração class para definir um novo 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
Em poucas palavras, uma classe é um conjunto de funções que realizam várias operações nas chamadas instâncias.
Instâncias são os objetos reais que você manipula em seu programa.
Elas são criadas chamando a classe como uma função.
>>> a = Player(2, 3)
>>> b = Player(10, 20)
>>>
a e b são instâncias de Player.
Enfatizando: A declaração da classe é apenas a definição (ela não faz nada por si só). Semelhante a uma definição de função.
Cada instância tem seus próprios dados locais.
>>> a.x
2
>>> b.x
10
Esses dados são inicializados pelo __init__().
class Player:
def __init__(self, x, y):
## Qualquer valor armazenado em `self` é dado da instância
self.x = x
self.y = y
self.health = 100
Não há restrições sobre o número total ou o tipo de atributos armazenados.
Métodos de instância são funções aplicadas a instâncias de um objeto.
class Player:
...
## `move` é um método
def move(self, dx, dy):
self.x += dx
self.y += dy
O próprio objeto é sempre passado como o primeiro argumento.
>>> a.move(1, 2)
## corresponde `a` a `self`
## corresponde `1` a `dx`
## corresponde `2` a `dy`
def move(self, dx, dy):
Por convenção, a instância é chamada de self. No entanto, o nome real usado não é importante. O objeto é sempre passado como o primeiro argumento. É apenas um estilo de programação Python chamar este argumento de self.
Classes não definem um escopo de nomes.
class Player:
...
def move(self, dx, dy):
self.x += dx
self.y += dy
def left(self, amt):
move(-amt, 0) ## NÃO. Chama uma função global `move`
self.move(-amt, 0) ## SIM. Chama o método `move` de cima.
Se você deseja operar em uma instância, você sempre se refere a ela explicitamente (por exemplo, self).
Começando com este conjunto de exercícios, começamos a fazer uma série de mudanças no código existente das seções anteriores. É fundamental que você tenha uma versão funcional do Exercício 3.18 para começar. Se você não tiver isso, trabalhe a partir do código da solução encontrado no diretório Solutions/3_18. É bom copiá-lo.
Nas seções 2 e 3, trabalhamos com dados representados como tuplas e dicionários. Por exemplo, uma participação em ações poderia ser representada como uma tupla assim:
s = ('GOOG',100,490.10)
ou como um dicionário assim:
s = { 'name' : 'GOOG',
'shares' : 100,
'price' : 490.10
}
Você pode até escrever funções para manipular esses dados. Por exemplo:
def cost(s):
return s['shares'] * s['price']
No entanto, à medida que seu programa cresce, você pode querer criar um senso melhor de organização. Assim, outra abordagem para representar dados seria definir uma classe. Crie um arquivo chamado stock.py e defina uma classe Stock que represente uma única participação em ações. Faça com que as instâncias de Stock tenham atributos name, shares e price. Por exemplo:
>>> import stock
>>> a = stock.Stock('GOOG',100,490.10)
>>> a.name
'GOOG'
>>> a.shares
100
>>> a.price
490.1
>>>
Crie mais alguns objetos Stock e manipule-os. Por exemplo:
>>> 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}')
... veja a saída ...
>>>
Uma coisa a enfatizar aqui é que a classe Stock age como uma fábrica para criar instâncias de objetos. Basicamente, você a chama como uma função e ela cria um novo objeto para você. Além disso, deve ser enfatizado que cada objeto é distinto - cada um tem seus próprios dados que são separados de outros objetos que foram criados.
Um objeto definido por uma classe é um pouco semelhante a um dicionário - apenas com uma sintaxe um pouco diferente. Por exemplo, em vez de escrever s['name'] ou s['price'], você agora escreve s.name e s.price.
Com classes, você pode anexar funções aos seus objetos. Estas são conhecidas como métodos e são funções que operam nos dados armazenados dentro de um objeto. Adicione um método cost() e sell() ao seu objeto Stock. Eles devem funcionar assim:
>>> 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
>>>
Tente estas etapas para criar uma lista de instâncias de Stock a partir de uma lista de dicionários. Em seguida, calcule o custo 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
>>>
Modifique a função read_portfolio() no programa report.py para que ela leia um portfólio em uma lista de instâncias de Stock, como mostrado no Exercício 4.3. Depois de fazer isso, corrija todo o código em report.py e pcost.py para que ele funcione com instâncias de Stock em vez de dicionários.
Dica: Você não deve precisar fazer grandes alterações no código. Você estará principalmente alterando o acesso a dicionários, como s['shares'], para s.shares.
Você deve ser capaz de executar suas funções da mesma forma que 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
>>>
Parabéns! Você concluiu o laboratório de Classes. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.