Agora que está claro o que é uma metaclasse , existe um conceito associado que eu uso o tempo todo sem saber o que realmente significa.
Suponho que todo mundo tenha cometido um erro entre parênteses, resultando em uma exceção "o objeto não pode ser chamado". Além do mais, usar __init__
e __new__
levar a se perguntar para que __call__
serve essa droga .
Você poderia me dar algumas explicações, incluindo exemplos com o método mágico?
Respostas:
Um indicativo é qualquer coisa que possa ser chamada.
A built-in que pode ser chamado (PyCallable_Check em objects.c) verifica se o argumento é:
__call__
método ouO método nomeado
__call__
é (de acordo com a documentação )Exemplo
fonte
callable
na verdade diz se algo pode ser chamado ou não, enquanto a verificação não__call__
diz nada; Se um objetoo
fornecer__getattribute__
ou__getattr__
,hasattr(o, '__call__')
pode retornar True, aindao
assim não será possível chamar porque o Python ignora__getattribute__
e faz__getattr__
chamadas. A única maneira real de verificar se algo pode ser chamado é, portanto, o EAFP.callable()
Python 3.x : " Esta função foi removida primeiro no Python 3.0 e depois trazida de volta no Python 3.2. ".tp_call
é verificada. Veja a implementação do PyCallable_Check , são 3 linhas.Nas fontes do Python, object.c :
Diz:
__call__
atributo.x
Caso contrário, o objeto pode ser chamado sex->ob_type->tp_call != NULL
Descrição do
tp_call
campo :Você sempre pode usar a
callable
função interna para determinar se um determinado objeto é chamador ou não; ou melhor ainda, basta ligar e pegarTypeError
mais tarde.callable
é removido no Python 3.0 e 3.1, usecallable = lambda o: hasattr(o, '__call__')
ouisinstance(o, collections.Callable)
.Exemplo, uma implementação simplista de cache:
Uso:
Exemplo de biblioteca padrão, arquivo
site.py
, definição de embutidosexit()
equit()
funções:fonte
def f(): ...
, e classe de objectos, tais comoclass C: ...
por exemplo,f
,''.strip
,len
, eC
todas podem ser chamados. Instâncias que possuem um__call__()
método em sua classe são relativamente raras.Um callable é um objeto que permite usar parênteses arredondados () e, eventualmente, passar alguns parâmetros, assim como funções.
Toda vez que você define uma função, o python cria um objeto que pode ser chamado. Por exemplo, você pode definir a função func das seguintes maneiras (é a mesma):
Você poderia usar esse método em vez de métodos como doit ou run , acho que é mais claro ver obj () do que obj.doit ()
fonte
Deixe-me explicar ao contrário:
Considere isto...
... como açúcar sintático para:
Onde
foo
pode ser qualquer objeto que responda__call__
. Quando digo qualquer objeto, falo sério: tipos internos, suas próprias classes e suas instâncias.No caso de tipos internos, quando você escreve:
Você está essencialmente fazendo:
É também por isso que você não possui
foo = new int
no Python: basta fazer com que o objeto de classe retorne uma instância dele__call__
. A maneira como o Python resolve isso é muito elegante na minha opinião.fonte
type(int).__call__(int, '10')
etype(unicode).__call__(unicode, '10')
. Dunders são sempre chamados em sua classe, não através da instância. E eles nunca passam pela metaclasse também. Na maioria dos casos, isso é apenas um detalhe, mas às vezes importa.Um Callable é um objeto que possui o
__call__
método Isso significa que você pode falsificar funções que podem ser chamadas ou fazer coisas legais, como Partial Function Application, onde você pega uma função e adiciona algo que a aprimora ou preenche alguns dos parâmetros, retornando algo que pode ser chamado por vez (conhecido como Currying nos círculos de programação funcional) )Certos erros tipográficos farão com que o intérprete tente chamar algo que você não pretendia, como (por exemplo) uma string. Isso pode gerar erros quando o intérprete tenta executar um aplicativo não solicitável. Você pode ver isso acontecendo em um intérprete python, fazendo algo como a transcrição abaixo.
fonte
__call__
torna qualquer objeto que pode ser chamado como uma função.Este exemplo produzirá 8:
fonte
Muito simplesmente, um "chamado" é algo que pode ser chamado como um método. A função interna "callable ()" informará se algo parece ser solicitável, assim como a verificação de uma propriedade de chamada . É possível chamar funções, assim como classes, instâncias de classe. Veja mais sobre isso aqui e aqui .
fonte
No Python, uma chamada é um objeto cujo tipo possui um
__call__
método:Tão simples como isso :)
Obviamente, isso pode ser sobrecarregado:
fonte
Verificar a função ou o método da classe é exigível ou não, o que significa que podemos chamar essa função.
fonte
callable(obj.__init___)
que não possui um sublinhado extra (como em AttributeError)? Caso contrário, você tem certeza de que a resposta não éTrue
essa?É algo que você pode colocar "(args)" depois e esperar que funcione. Uma chamada é geralmente um método ou uma classe. Os métodos são chamados, as classes são instanciadas.
fonte
callables implementam o
__call__
método especial para que qualquer objeto com esse método possa ser chamado.fonte
__call__
não poderá ser chamada se a classe não definir esse método.Callable é um tipo ou classe de "Função ou Método Integrado" com uma chamada de método
Exemplo: print é um objeto que pode ser chamado. Com uma função interna __call__ Quando você invoca a função print , o Python cria um objeto do tipo print e invoca seu método __call__ passando os parâmetros, se houver.
Obrigado. Atenciosamente, Maris
fonte
print
função, o Python cria um objeto do tipo print e invoca seu método__call__
". Python não cria um objeto de impressão. Apenas chama algo equivalente atype(print).__call__(print, *args, **kwargs)
. E a primeira frase não faz muito sentido. Você parece estar confundindo um objeto que pode ser chamado e "chamado" da função.