Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Encapsulamento de atributos em Python

Encapsulamento de atributos em Python

Apresentado no encontro do GruPy-SP na SciELO, dia 13 de agosto de 2016.

Avatar for Gustavo Fonseca

Gustavo Fonseca

August 13, 2016

Other Decks in Programming

Transcript

  1. In programming languages, encapsulation is used to refer to one

    of two related but distinct notions, and sometimes to the combination thereof: • A language mechanism for restricting direct access to some of the object's components. • A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data. https://en.wikipedia.org/w/index.php?title=Encapsulation_(computer_programming)&oldid=731002333 ocultação da informação
  2. OCULTAÇÃO DA INFORMAÇÃO A representação interna do objeto é oculta

    do ponto de vista do seu usuário. Algumas linguagens permitem que níveis de acesso sejam especificados por meio de palavras como private e public. 1 #include <iostream> 2 class Example { 3 public: 4 void add(int x) { 5 n += x; 6 } 7 private: 8 int n = 0; 9 }; 10 int main() 11 { 12 Example e; 13 e.add(1); 14 // e.n = 7; 15 } erro de acesso http://en.cppreference.com/w/cpp/language/access
  3. OCULTAÇÃO DA INFORMAÇÃO Em Python, todas as variáveis são públicas

    e não existe o conceito de variáveis privadas.
  4. CONFLITO DE NOMES 1 class Mapeamento: 2 def __init__(self, iteraável):

    3 self.itens = [] 4 self.atualiza(iterável) 5 6 def atualiza(self, iterável): 7 for item in iterável: 8 self.itens.append(item) 9 10 11 unidades_federativas = [ 12 ('AC', 'Acre'), 13 ('AL', 'Alagoas'), 14 ('AP', 'Amapá'), 15 ] 16 mapa_uf = Mapeamento(unidades_federativas) 17 print('Itens:', mapa_uf.itens) 18 19 mapa_uf.atualiza([('AM', 'Amazonas'), ('BA', 'Bahia'), ('CE', 'Ceará')]) 20 print('Itens após atualização:', mapa_uf.itens) saída no console
  5. 1 import mapping 2 3 class MapeamentoZip(mapping.Mapeamento): 4 def atualiza(self,

    chaves, valores): 5 for item in zip(chaves, valores): 6 self.itens.append(item) 7 8 9 unidades_federativas = [ 10 ('AC', 'Acre'), 11 ('AL', 'Alagoas'), 12 ('AP', 'Amapá'), 13 ] 14 mapa_uf = MapeamentoZip(unidades_federativas) 15 16 abreviações = ['AM', 'BA', 'CE'] 17 estados = ['Amazonas', 'Bahia', 'Ceará'] 18 19 mapa_uf.atualiza(abreviações, estados) 20 print('Itens após atualização:', mapa_uf.itens) Eu gostaria da seguinte API: abreviações = [‘AM’, ‘BA’, ‘CE’] estados = [‘Amazonas’, ‘Bahia’, ‘Ceará’] mapa_uf.atualiza(abreviações, estados) o inicializador
 depende do método "atualiza"
  6. 1 class Mapeamento: 2 def __init__(self, iterável): 3 self.itens =

    [] 4 self.__atualiza(iterável) 5 6 def atualiza(self, iterável): 7 for item in iterável: 8 self.itens.append(item) 9 10 __atualiza = atualiza cópia privada 
 do método ????????????????????????????????????????
  7. DESFIGURAÇÃO DE NOME Conflitos de nomes em subclasses são evitados

    por meio do mecanismo de Name Mangling. 1 class Foo: 2 def __init__(self): 3 self.bar = 'bar' 4 self._ble = 'ble' 5 self.__zap = 'zap' 6 7 8 foo = Foo() 9 print(dir(foo)) 10 11 print('bar:', foo.bar) 12 print('_ble:', foo._ble) 13 print('__zap', foo.__zap) 14 nome desfigurado
  8. In programming languages, encapsulation is used to refer to one

    of two related but distinct notions, and sometimes to the combination thereof: • A language mechanism for restricting direct access to some of the object's components. • A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data. https://en.wikipedia.org/w/index.php?title=Encapsulation_(computer_programming)&oldid=731002333 restrição de acesso direto
  9. Imagine um objeto parecido com uma struct da linguagem C…

    1 class Música: 2 título = '' 3 artista = '' 4 duração = 0 5 6 7 bad = Música() 8 bad.título = 'Bad' 9 bad.artista = 'Michael Jackson' 10 bad.duração = 247 11 12 crush = Música() 13 crush.título = 'Crush' 14 crush.artista = 'Dave Matthews Band' 15 crush.duração = 489 16 17 mais_longa = max([bad, crush], key=lambda música: música.duração) 18 print('A música mais longa é "{}" do artista "{}".'.format( 19 mais_longa.título, mais_longa.artista)) 20 E se trocarmos para: crush.duração = '489' ? TypeError
  10. 1 class Música: 2 título = '' 3 artista =

    '' 4 5 @property 6 def duração(self): 7 try: 8 return self._duração 9 except AttributeError: 10 return 0 11 12 @duração.setter 13 def duração(self, valor): 14 self._duração = int(valor) 15 16 17 bad = Música() 18 bad.título = 'Bad' 19 bad.artista = 'Michael Jackson' 20 bad.duração = 247 21 22 crush = Música() 23 crush.título = 'Crush' 24 crush.artista = 'Dave Matthews Band' 25 crush.duração = '489' 26 27 mais_longa = max([bad, crush], key=lambda música: música.duração) 28 print('A música mais longa é "{}" do artista "{}".'.format( 29 mais_longa.título, mais_longa.artista)) 30 31 32 crush.duração = 'Groselha' getter setter Beleza! ERRO! PROPERTIES
  11. 1 class Música: 2 título = '' 3 artista =

    '' 4 5 @property 6 def duração(self): 7 try: 8 return self._duração 9 except AttributeError: 10 return 0 11 12 @duração.setter 13 def duração(self, valor): 14 self._duração = int(valor) 15 16 @property 17 def ano_lançamento(self): 18 try: 19 return self._ano_lançamento 20 except AttributeError: 21 return 0 22 23 @ano_lançamento.setter 24 def ano_lançamento(self, valor): 25 self._ano_lançamento = int(valor) 26 27 28 bad = Música() 29 bad.título = 'Bad' 30 bad.artista = 'Michael Jackson' 31 bad.duração = 247 32 bad.ano_lançamento = 1987 Adicionamos o atributo ano_lançamento, com a mesma restrição de duração. Repare como os blocos de código se repetem.
  12. DESCRIPTORS Descritor é um atributo de classe que controla a

    semântica da atribuição e acesso a um atributo na instância da classe. Protocolo: descr.__get__(self, obj, type=None) —> value
 descr.__set__(self, obj, value) —> None
 descr.__delete__(self, obj) —> None
  13. 1 class NúmeroInteiro: 2 def __init__(self, nome): 3 self.nome =

    '_' + nome 4 5 def __set__(self, instância, valor): 6 _valor = int(valor) 7 setattr(instância, self.nome, _valor) 8 9 def __get__(self, instância, classe): 10 return getattr(instância, self.nome) 11 12 13 class Música: 14 título = '' 15 artista = '' 16 duração = NúmeroInteiro('duração') 17 ano_lançamento = NúmeroInteiro('ano_lançamento') 18 19 20 bad = Música() 21 bad.título = 'Bad' 22 bad.artista = 'Michael Jackson' 23 bad.duração = 247 24 bad.ano_lançamento = 1987 25 bad.ano_lançamento = 'blé' # levanta exceção!