0% acharam este documento útil (0 voto)
3 visualizações10 páginas

Herança e Metaprogramação em Python

O documento aborda conceitos avançados de Python, incluindo herança de tipos internos, simulação de dicionários e o uso de metaclasses. Exemplos práticos são fornecidos para ilustrar a criação de classes, métodos especiais como __init__ e __new__, e a implementação de padrões como singleton. O conteúdo é voltado para usuários que desejam aprofundar seus conhecimentos em Python e suas funcionalidades avançadas.

Traduzido por

ScribdTranslations
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
3 visualizações10 páginas

Herança e Metaprogramação em Python

O documento aborda conceitos avançados de Python, incluindo herança de tipos internos, simulação de dicionários e o uso de metaclasses. Exemplos práticos são fornecidos para ilustrar a criação de classes, métodos especiais como __init__ e __new__, e a implementação de padrões como singleton. O conteúdo é voltado para usuários que desejam aprofundar seus conhecimentos em Python e suas funcionalidades avançadas.

Traduzido por

ScribdTranslations
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Python Avançado

Ernesto Revilla
Software Integrado para o Controle de Empresas, Lda.

GCubo: Grupo de usuários de GNU/Linux de Granada

[Link]. Informática (Univ. Granada)


Abril 2004

GCubo: Grupo de usuários de GNU/Linux de Granada


Herencia simple desde tipos internos
Python, desde a versão 2.2, permite herdar de tipos de dados internos,
como:

int, float, complex, str, unicode

list, dict, tuple
classe DefaultDict(dict):
def __init__(self, valoresIniciais=None, padrao=0.0):
dict.__init__(valoresIniciais ou {})
self._default=default
def __getitem__(self, key):
tente:
return dict.__getitem__(self, chave)
exceto KeyError:
return self._default
se __nome__=="__principal__":
d=DefaultDict({'a': 5})
print 'valor de e:', d['e']
print 'valor de a:', d['a']

Veja [Link]

GCubo: Grupo de usuários de GNU/Linux de Granada


Simular tipos internos 1
Existem construções sintáticas que facilitam a redação dos programas,
como [ ], { }, !=, ... Podemos personalizar seu comportamento.
Realizamos um dicionário por delegação:
class MiDicc:
def __init__(self, diccInicial=None):
self._dicc=dict(diccInicial ou {})
def __getitem__(self, item):
lendo, item
return self._dicc[item]
def __setitem__(self, item, valor):
print "estabelecendo", item
self._dicc[item]=valor
def zap(self):
self._dicc={}
def __getattr__(self, attr):
se attr estiver em ['itens', 'chaves', 'valores']:
return getattr(self._dicc, attr)

Veja [Link].

GCubo: Grupo de usuários de GNU/Linux de Granada


Simular tipos internos 2
Usar as entradas do dicionário como atributos:
classe MiDicc2(MiDicc):
def __getattr__(self, attr):
return MiDicc.__getitem__(self, attr)
def __setattr__(self, attr, valor):
MiDicc.__setitem__(self, attr, valor)
produzir bucle infinito!!, ao estabelecer atributo _dicc em MiDicc
def __setattr__(self, attr, valor):
se attr não estiver em ['_dicc']:
MiDicc.__setitem__(self, attr, valor)
senão:
MiDicc.__dict__['_dicc']=valor
# se MiDicc tivesse herdado de object
# MiDicc.__setattr__(self, attr, valor)

Veja [Link].

GCubo: Grupo de usuários de GNU/Linux de Granada


Um exemplo prático
Para este ejemplo es necesario tener la base de datos sqlite ([Link]),
como também o binding para python ([Link]).
Conexão a um bd sqlite:

importar sqlite
con=[Link]('[Link]')
cur=[Link]()
def criarTabela():
[Link]("criar tabela personas (num inteiro, "
"nombre text, "apellidos text, edad integer;")
def insertarDatosEjemplo():
personas=[ [1, 'Erny', 'Revilla'], [2, 'Lorenzo', 'Gil'],
[3, 'Dani', 'Molina']]
para persona em personas:
[Link]("insert into personas (num, nombre, "
apellidos) valores (%s, '%s', '%s');

Veja os arquivos [Link], [Link] e [Link] que mostram como pode ser criada uma
pequeña capa de persistencia para objetos.

GCubo: Grupo de utilizadores de GNU/Linux de Granada


Coisas sobre __init__

__init__ representa o método de inicialização de instância, não é o
inicializador (como em c++) em vez de construtor.

__init__ é chamado depois que a memória foi reservada e realizada
uma mínima inicialização do objeto.

ao realizar herança múltipla, é necessário definir __init__ para indicar o
ordem das chamadas de __init__ das superclasses
classe A(object):
def __init__(self):
print "__init__ de A"
classe B(objeto):
def __init__(self):
print "__init__ de B"
class C(A,B): pass # isso está errado!!!
c=C()
classe C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self)
Veja [Link] GCubo: Grupo de usuários de GNU/Linux de Granada
__new__, o construtor

__new__ é sempre um método de classe

__new__ aparece en la versión 2.2 de python

com __new__ também se podem devolver instâncias de outros tipos.
Exemplos:
classe A (objeto):
def __init__(self, *args, **kwargs):
print "criando objeto do tipo A com "
"argumentos pos. %s y argumentos nombrados %s"
% (args, kwargs)

# devolver outros tipos de objetos


classe B(objeto):
def __new__(cls, *args, **kwargs):
retornar A(*args, **kwargs)
x=B(1,2, pepe='no')

Veja [Link]

GCubo: Grupo de usuários de GNU/Linux de Granada


__new__: singleton
# singleton:
classe Singleton(object):
_instance=None
def __new__(cls, *args, **kwargs):
se não cls._instance:
Criando Singleton
cls._instance=object.__new__(cls, *args,
**kwargs)
return cls._instance

def __init__(self, *args, **kwargs):


Inicializando Singleton

s=Singleton()
s=Singleton()

GCubo: Grupo de usuários de GNU/Linux de Granada


Metaclases

Ao terminar a leitura da definição de uma classe, o Python cria esta usando
una metaclase de forma Metaclase(nombre, superclases, diccionario)

Nome é o nome da classe, Superclasses é uma tupla

dicionário contém as funções e identificadores definidos dentro da
classe

Atualmente (>=2.2) usa duas metaclasses, uma para as classes antigas
([Link]) e outra para os novos (type)

Na metaclasse, podemos definir novos atributos ou funções para a classe
class Metaclasse(type):
def __init__(self, nome, bases, dic):
type.__init__(self, nome, bases, dic)
Definindo classe %s:
imprimir "Bases: %s" % (bases ou None)
print "Dict: %s" % dic
classe A(objeto):
__metaclass__=Metaclase
_attributes=["at1","at2","at3"]
y=5
def __init__(self):
self.x=10 GCubo: Grupo de usuários de GNU/Linux de Granada
Metaclases 2
Veja [Link] para o exemplo anterior.

O seguinte exemplo cria novos métodos em uma classe (getters e setters) para
os atributos especificados.
class Metaclase(type):
def __init__(self, nome, bases, dic):
type.__init__(self, nome, bases, dic)
se "_attributes" em dic:
para attr em dic['_atributos']:
f=lambda s,a=attr: getattr(s,a)
setattr(self, 'get'+attr, f)
f=lambda s, valor, a=attr: setattr(s,a,valor)
setattr(self, 'set' + attr, f)

Veja [Link]

GCubo: Grupo de usuários de GNU/Linux de Granada

Você também pode gostar