Como faço para disputar pesquisas Python: make.up.a.dot.separated.name.and.use.it.until.destroyed = 777
-
05-07-2019 - |
Pergunta
Eu sou um novato Python com uma coceira muito particular a experiência com o processo de-ponto-de pesquisa de nome do Python. Como eu código de uma classe ou função em "make.py" para que estas instruções de atribuição trabalhar com sucesso?
import make
make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
Solução
#!/usr/bin/env python
class Make:
def __getattr__(self, name):
self.__dict__[name] = Make()
return self.__dict__[name]
make = Make()
make.a.dot.separated.name = 666
make.anything.i.want = 777
print make.a.dot.separated.name
print make.anything.i.want
O método __getattr__
especial é chamado quando um valor nomeado não foi encontrado. As extremidades linha make.anything.i.want
fazendo o equivalente a:
m1 = make.anything # calls make.__getattr__("anything")
m2 = m1.i # calls m1.__getattr__("i")
m2.want = 777
A implementação acima usa essas chamadas para __getattr__
para criar uma cadeia de Make
objetos cada vez que uma propriedade desconhecida é acessado. Isso permite que o ponto acessa a ser aninhados arbitrariamente profunda até que o trabalho final em que ponto um valor real é atribuído.
Python documentação - personalização de acesso atributo :
object.__getattr__(self, name)
Chamado quando uma pesquisa de atributo não encontrou o atributo nos locais habituais (ou seja, não é um atributo instância nem é encontrado na árvore de classe para
self
).name
é o nome do atributo. Este método deve retornar o (computadorizada) valor do atributo ou levantar uma exceçãoAttributeError
.Note que, se o atributo é encontrado através do mecanismo normal,
__getattr__()
não é chamado. (Esta é uma assimetria intencional entre__getattr__()
e__setattr__()
.) Isto é feito tanto por razões de eficiência e porque senão__getattr__()
não teria nenhuma maneira de acessar outros atributos da instância. Note-se que, pelo menos para as variáveis ??de instância, você pode total controle falso por não inserir quaisquer valores no dicionário atributo de instância (mas em vez de inseri-los em outro objeto). Veja o método__getattribute__()
abaixo uma maneira de realmente obter o controle total em classes new-style.
object.__setattr__(self, name, value)
Chamado quando uma atribuição atributo é tentada. Isto é chamado em vez do mecanismo normal (isto é armazenar o valor no dicionário exemplo).
name
é o nome do atributo,value
é o valor a ser atribuído a ele.Se
__setattr__()
quer atribuir a um atributo exemplo, não deve simplesmente executarself.name = value
- isso causaria uma chamada recursiva para si. Em vez disso, ele deve inserir o valor no dicionário de atributos de instância, por exemplo,self.__dict__[name] = value
. Para as classes de estilo novo, em vez de acessar o dicionário exemplo, ele deve chamar o método da classe base com o mesmo nome, por exemplo,object.__setattr__(self, name, value)
.