Como faço para disputar pesquisas Python: make.up.a.dot.separated.name.and.use.it.until.destroyed = 777

StackOverflow https://stackoverflow.com/questions/1602745

  •  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
Foi útil?

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ção AttributeError.

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 executar self.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).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top