Os segredos sombrios do type
Posted on Sex 22 janeiro 2016 in Builtin
Sobre o type:
O type do Python tem um uso comum, assim como seus respectivos em cada linguagem, que é de verificar os tipos dos objetos, como em Javascript, por exemplo, com o typeof você verifica os tipos de variáveis e objetos como String, Number, Array e etc. Porém, no Python type é muito mais importante e poderoso, pois ele é o ator principal e base de todos os objetos Python. Vamos ver com nossos próprios olhos. Abra um terminal python e digite:
In [1]: print str.__class__
Out[1]: type
In [2]: print int.__class__
Out[2]: type
Ou simplesmente:
In [3]: print type(float)
Out[3]: type
In [3]: print type(type)
Out[3]: type
Podemos dizer que type é a base de todos os tipos de objetos em python. Tudo em python é e vem dele.
"Mas como assim type é a base de tudo em Python", você deve se perguntar. Vamos ver seu poder mais obscuro e talvez menos conhecido.
Os poderes sombrios de type:
O tipo type quando chamado com 1 argumento apenas lhe devolve o tipo do objeto em questão, porém ele aceita mais 2 argumentos, que quando usados, produzem um resultado que talvez poucos conheçam, repare bem no exemplo abaixo:
# Criando uma classe da maneira tradicional em python
class Foo(object):
foo = 'Foo class'
# Imprimindo o atributo foo de Foo
In [1]: Foo.foo
Out[1]: 'Foo class'
# Agora criando uma class utilizando os poderes de type
Bar = type('Bar', (), {'bar': 'Bar class'})
# Imprimindo o atributo bar de Bar criado pelo type
In [2]: Bar.bar
Out[2]: 'Bar class'
Legal não? Agora vamos ver quais argumentos precisamos para criar uma classe utilizando type.
# Imprimindo parte da doc
Type: type
String form: <type 'type'>
Namespace: Python builtin
Docstring:
type(object) -> the object's type
type(name, bases, dict) -> a new type
Args:
1º argumento é uma string que vai ser o nome base da sua classe
2º argumento é uma tupla com os objetos(classes) que você deseja herdar atributos por exemplo.
3º argumento é um dicionário com as propriedades que sua classe deve possuir.
Outro exemplo para melhor clarificação:
class Foo(object):
def __init__(self):
print "Hello {}".format(self.__class__.__name__)
foo = Foo()
print Foo.__base__
# Imprime:
# Hello Foo
# <type 'object'>
# Herdando de Foo
Bar = type('Bar', (Foo,), {'bar':'Atributo bar'})
bar = Bar()
print bar.bar
print Bar.__base__
# Imprime:
# Hello Bar
# Atributo bar
# <class '__main__.Foo'>
Explicando: Criamos a classe Foo da maneira tradicional em python, e depois criamos Bar utilizando type e herdando características de Foo e adicionando um atributo com o nome de "bar". Veja que o funcionamento é identico para criar uma classe da maneira tradicional ou com type.
Utilidade
A utilidade de criar classes com type podem ou não ser vantajosas, isto depende do uso, mas um exemplo comum, é quando utilizado para criar classes dinâmicas que precisam de heranças, atributos e comportamentos diferentes de acordo com a necessidade, simplesmente passando objetos dinamicos seguindo a ordem:
type([str], [tuple], [dict])
# str(nome), tuple(classe) e dict(atributos)
Para não digitar mais nenhum exemplo chato, vou passar um uso simples de type que está em uso em uma lib famosa sandman(que é utilizada para criar APIs REST dinamicas com base em um banco de dados sem muito esforço). Clique no link abaixo:
Espero que tenham gostado, e espero que possa ser útil para vocês, como acabou sendo para mim.