Programação Orientada a Objetos em Python Dilvan Moreira
Lembrando: Métodos e funções em Dicionários Importante: As chaves do dicionário são únicas e imutáveis. Tabela de métodos e operadores em Dicionários: Método ou operadorAção d[key]get the value of the entry with key key in d d[key] = valset the value of entry with key key to val del d[key]delete entry with key key d.clear()removes all entries len(d)number of items d.copy()makes a shallow copy* d.has_key(key)returns 1 if key exists, 0 otherwise
Lembrando: Métodos e funções em Dicionários Continuação... Tabela de métodos e operadores em Dicionários: Método ou operadorAção d.keys()gives a list of all keys d.values()gives a list of all values d.items()returns a list of all items as tuples (key,value) d.update(new)adds all entries of dictionary new to d d.get(key [, otherwise])returns value of the entry with key key if it exists otherwise returns otherwise d.setdefaults(key [, val])same as d.get(key), but if key does not exists sets d[key] to val d.popitem()removes a random item and returns it as tuple
Objetivos Aprender como é a programação Orientada a Objetos no Python. Leitura: Do livro “Como Pensar como um Cientísta da Computação usando Python” Cap. 12 do livro “Think Python” Cap. 15 e 16
Prog. Orientada a Objetos Um estilo de programação onde todos os componentes de um programa são considerados objetos Objetos são componentes que têm estado, comportamento e identidade Modelam objetos da vida real Guias e técnicas para manter essa abstração de maneira inteligente
Tipos definidos pelo usuário Usamos muitos tipos de dados nativos do Python E se quisermos criar um tipo novo? Que não existe em Python. Criaremos um tipo denominado Point, por exemplo: Point é um ponto num espaço bidimensional. Na Matemática são representado como: e (x,y) X unidades horizontais Y unidades verticais
Tipos definidos pelo usuário Podemos representar um ponto de diversas maneiras no Python. Armazenar as coordenadas separadamente em X e Y Armazenar como elementos de uma lista ou tupla Criar um novo tipo Point para representar os pontos como objetos
Tipos definidos pelo usuário Criar um novo tipo de dados Mais complicado (só um pouco), Tem vantagens, que você ira perceber rapidamente. class Point(): """represents a point in 2-D space""” x=0.0 y=0.0 “Este cabeçalho representa que a nova classe é um ponto, e que é um tipo de objeto”
Tipos definidos pelo usuário Nota: podemos definir variáveis e funções dentro de uma definição de classe, porem vamos ver isso somente mais tarde! Definindo uma classe chamada Point criamos uma classe (tipo) de objetos. >>> print Point Porque o Point é definido no nível superior, seu “nome completo” é __main__.Point
Tipos definidos pelo usuário A Classe de Objeto é como uma fábrica de objetos. Para criar um ponto: >>> blank = Point() >>> print blank O valor de retorno é uma referência a um objeto Point
Tipos definidos pelo usuário Criar um novo objeto é chamado de instanciação, ou seja o objeto é uma instancia de uma classe. Quando você imprime um exemplo, fala ao Python que a classe a que pertence e onde é armazenado na memoria.
Atributos Atribuímos valores a uma instancia usando a notação de ponto: >>> blank.x = 3.0 >>> blank.y = 4.0 Muito parecido quando selecionamos uma variável de um modulo: math.pi ou string.whitespace Porém, nos estamos atribuindo valores aos elementos de um objeto. Esses elementos chamamos de Atributos
Atributos O diagrama abaixo mostra o resultado desse trabalho. Um diagrama de estado mostrando um objeto e seus atributos e é chamado de Diagrama de Objeto
Atributos Você pode ler um valor de um atributo: >>> print blank.y 4.0 >>> x = blank.x >>> print x 3.0 A expressao blank.x significa: “Pegue o valor da referencia x do objeto blank ” Neste caso, nós atribuímos o valor a uma variável x, não há conflito entre a variável e o atributo.
Atributos Você pode usar a notação de ponto como parte de qualquer expressão: >>> print blank.x, blank.y >>> distance = math.sqrt(blank.x**2 + blank.y**2) >>> print distance 5.0
Atributos Você pode passar uma instância como um argumento: def print_point(p): print '(', p.x, ',', p.y, ')' print_point recebe um Point como parâmetro e imprime o valor como notação matemática: >>> print_point(blank) (3.0, 4.0)
Atributos Nota: Dentro da função, a variável p contém uma referência para o objeto que está na variável blank, assim se modificarmos p na função, as mudanças serão afetadas em blank. Exercicio: Escreva uma função chamada distance que leva dois pontos como argumento e retorna a distancia entre eles.
Retângulos Às vezes é óbvio quais atributos um objeto devem ter, mas, em outras vezes, você tem que tomar decisões. Por exemplo: imagine que você está criando uma classe para representar retângulos: Quais os atributos que você usaria para especificar a localização e o tamanho de um retângulo? Você pode ignorar ângulo para manter as coisas simples. Assuma que o retângulo é vertical ou horizontal.
Retângulos Existem duas possibilidades: Podemos especificar um canto do retângulo (ou centro), a largura e altura. Podemos especificar dois cantos opostos. Nesse ponto de vista, é difícil dizer qual é o melhor, porém, vamos implementar o primeiro como um exemplo.
Retângulos Aqui esta a definição da classe: class Rectangle(): """represent a rectangle. attributes: width, height, corner. """ width= 0.0 height= 0.0 corner= Point() Dentro é definido a lista de atributos: width e height que são números, o corner é um objeto Point que especifica o canto inferior esquerdo.
Retângulos Para representar um retângulo, vamos instanciar um objeto retângulo e atribuir os atributos: box = Rectangle() box.width = box.height = box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0
Retângulos A expressão box.corner.x significa: “Vá para referencia do objeto box e selecione o atriburo chamado corner, então vá ao objeto e selecione o atributo chamado x ” A figura mostra o estado deste objeto: Um objeto que é um atributo de outro objeto.
Instâncias com valores de retorno Funções podem retornar instâncias. Exempo: a função find_center pega um Rectangle como argumento e retorna um Point que contem as coordenadas do centro do retângulo. def find_center(box): p = Point() p.x = box.corner.x + box.width/2.0 p.y = box.corner.y + box.height/2.0 return p
Instâncias com valores de retorno Um exemplo que pega um box como argumento e o resultado como Point do centro. >>> center = find_center(box) >>> print_point(center) (50.0, 100.0)
Objetos são mutáveis Você pode alterar o estado de um objeto fazendo uma atribuição em um de seus atributos: Exemplo: para alterar o tamanho do retângulo sem mudar sua posição, você pode modificar os valores de width e height box.width = box.width + 50 box.height = box.width + 100
Objetos são mutáveis Você pode escrever funções que modifiquem os objetos. Exemplo: grow_rectangle leva um objeto Rectangle e dois números, dwidth e dheight e acrescenta os numeros a largura e altura do retângulo: def grow_rectangle(rect, dwidth, dheight) : rect.width += dwidth rect.height += dheight
Objetos são mutáveis Um exemplo que demonstra o efeito: >>> print box.width >>> print box.height >>> grow_rectangle(box, 50, 100) >>> print box.width >>> print box.height 300.0
Copiando Copiando Objetos O exemplo contém uma função chamada 'copy' que duplica um qualquer objeto: >>> p1 = Point() >>> p1.x = 3.0 >>> p1.y = 4.0 >>> import copy >>> p2 = copy.copy(p1)
Copiando p1 e p2 tem os mesmo dados, porém não são o mesmo Point : >>> print_point(p1) (3.0, 4.0) >>> print_point(p2) (3.0, 4.0) >>> p1 is p2 False >>> p1 == p2 False Infelizmente: para instancias o operador == é o mesmo que o operador is ele checa identidade e não equivalência
Copiando Se você usar copy.copy para duplicar um Rectangle, você vai achar que ele copia o objeto Rectangle, mas não o Point embutido: >>> box2 = copy.copy(box) >>> box2 is box False >>> box2.corner is box.corner True
Copiando O diagrama de objeto: Esta operação é chamada de cópia superficial porque ele copia o objeto e as referências que ele contém, mas não os objetos incorporados.
Copiando O método deepcopy – copia o objeto e todos os objetos que ele os referencia: >>> box3 = copy.deepcopy(box) >>> box3 is box False >>> box3.corner is box.corner False box3 e box são objetos completamente separados.
Copiando Tente não usar copias Elas são custosas Suscetíveis a erros Seu uso em demasia indica provável erro de projeto Tente usar objetos imutáveis Tente não mudar o conteúdo dos objetos Todos podem ter referências para eles Não há a necessidade de cópias
Classes e funções – Time Como outro exemplo de tipos definidos pelo usuário, podemos criar uma classe chamada Time para registrar a hora do dia: class Time(): """represents the time of day. attributes: hour, minute, second""" hour= 0 minute= 0 second= 0
Classes e funções – Time Podemos criar um novo objeto Time e determinar atributos para horas, minutos e segundos: time = Time() time.hour = 11 time.minute = 59 time.second = 30
Classes e funções – Time O diagrama de estado para o objeto Time:
Perguntas?