Eu ligetattr()
recentemente sobre a função . O problema é que ainda não consigo entender a ideia de seu uso. A única coisa que entendo getattr()
é que getattr(li, "pop")
é o mesmo que ligar li.pop
.
Não entendi quando o livro mencionou como você o usa para obter uma referência a uma função sem saber seu nome até o tempo de execução. Talvez este seja eu sendo um noob em programação, em geral. Alguém poderia lançar alguma luz sobre o assunto? Quando e como uso exatamente isso?
Respostas:
getattr(object, 'x')
é completamente equivalente aobject.x
.Existem apenas dois casos em que
getattr
podem ser úteis.object.x
, porque não sabe com antecedência qual atributo deseja (vem de uma string). Muito útil para meta-programação.object.y
aumentará umAttributeError
se não houvery
. Masgetattr(object, 'y', 5)
vai voltar5
.fonte
Objetos no Python podem ter atributos - atributos e funções de dados para trabalhar com esses (métodos). Na verdade, todo objeto possui atributos internos.
Por exemplo, você tem um objeto
person
, que tem vários atributos:name
,gender
, etc.Você acessa esses atributos (seja métodos ou objetos de dados) normalmente escrever:
person.name
,person.gender
,person.the_method()
, etc.Mas e se você não souber o nome do atributo no momento em que escreve o programa? Por exemplo, você tem o nome do atributo armazenado em uma variável chamada
attr_name
.E se
então, ao invés de escrever
você pode escrever
Alguma prática:
getattr
aumentaráAttributeError
se o atributo com o nome fornecido não existir no objeto:Mas você pode passar um valor padrão como o terceiro argumento, que será retornado se esse atributo não existir:
Você pode usar
getattr
junto comdir
para iterar todos os nomes de atributos e obter seus valores:Um uso prático para isso seria encontrar todos os métodos cujos nomes começam
test
e os chamam .Semelhante ao
getattr
que hásetattr
que lhe permite definir um atributo de um objeto que tem o seu nome:fonte
getattr(..)
deve ser usado em 2 cenários: 1. quando o nome do atributo é um valor dentro de uma variável (por exemplogetattr(person, some_attr)
) e 2. quando precisamos usar o terceiro argumento posicional para o valor padrão (por exemplogetattr(person, 'age', 24)
). Se vejo um cenário comogetattr(person, 'age')
esse, parece-me idêntico aoperson.age
que me leva a pensar queperson.age
é mais pitônico. Isso está correto?Para mim,
getattr
é mais fácil explicar dessa maneira:Ele permite que você chame métodos com base no conteúdo de uma string em vez de digitar o nome do método.
Por exemplo, você não pode fazer isso:
porque x não é do tipo
builtin
, masstr
. No entanto, você pode fazer isso:Ele permite que você se conecte dinamicamente com objetos com base em sua entrada. Eu achei útil ao lidar com objetos e módulos personalizados.
fonte
Um caso de uso bastante comum
getattr
é o mapeamento de dados para funções.Por exemplo, em uma estrutura da web como Django ou Pylons,
getattr
é fácil mapear o URL de uma solicitação da web para a função que irá lidar com isso. Se você olhar sob o capô do roteamento do Pylons, por exemplo, verá que (por padrão, pelo menos) ele divide o URL de uma solicitação, como:em "clientes" e "lista". Em seguida, ele procura uma classe de controlador chamada
CustomerController
. Supondo que encontre a classe, ele cria uma instância da classe e usagetattr
para obter seulist
método. Em seguida, chama esse método, passando a solicitação como argumento.Depois de entender essa idéia, fica muito fácil estender a funcionalidade de um aplicativo Web: basta adicionar novos métodos às classes do controlador e criar links nas suas páginas que usem os URLs apropriados para esses métodos. Tudo isso é possível graças a
getattr
.fonte
Aqui está um exemplo rápido e sujo de como uma classe pode disparar versões diferentes de um método save, dependendo do sistema operacional que está sendo executado
getattr()
.Agora vamos usar esta classe em um exemplo:
fonte
Além de todas as respostas surpreendentes aqui, há uma maneira de usar
getattr
para salvar linhas de código copiosas e mantê-las confortáveis. Esse pensamento veio após a terrível representação do código que às vezes pode ser uma necessidade.Cenário
Suponha que sua estrutura de diretórios seja a seguinte:
E, você tem funções para obter informações sobre
Thor
,Iron Man
,Doctor Strange
emsuperheroes.py
. Você muito inteligente anota as propriedades de todas elas deproperties.py
forma compactadict
e as acessa.properties.py
Agora, digamos que você queira retornar os recursos de cada um deles sob demanda
superheroes.py
. Então, existem funções como... e mais funções retornando valores diferentes com base nas chaves e no super-herói.
Com a ajuda de
getattr
, você pode fazer algo como:Você reduziu consideravelmente o número de linhas de código, funções e repetição!
Ah, é claro, se você tem nomes ruins como
properties_of_thor
para variáveis, eles podem ser criados e acessados simplesmente fazendoNOTA: Para esse problema em particular, pode haver maneiras mais inteligentes de lidar com a situação, mas a idéia é fornecer uma visão sobre o uso
getattr
nos locais certos para escrever um código mais limpo.fonte
fonte
Às vezes eu uso
getattr(..)
para inicializar preguiçosamente atributos de importância secundária pouco antes de serem usados no código.Compare o seguinte:
Para isso:
A vantagem da segunda maneira é que
n_calls_to_plot
apenas aparece em torno do local no código em que é usado. Isso é bom para facilitar a leitura, porque (1) você pode ver imediatamente com que valor ele começa quando lê como é usado; (2) não introduz uma distração no__init__(..)
método, o que idealmente deveria ser sobre o estado conceitual da classe. , em vez de algum contador de utilidade que é usado apenas por um dos métodos da função por razões técnicas, como otimização, e não tem nada a ver com o significado do objeto.fonte
Com bastante frequência, ao criar um arquivo XML a partir de dados armazenados em uma classe, eu frequentemente recebia erros se o atributo não existisse ou fosse do tipo
None
. Nesse caso, meu problema não era saber qual era o nome do atributo, conforme declarado na sua pergunta, mas sim os dados já armazenados nesse atributo.Se eu
hasattr
fizesse isso, ele retornariaTrue
mesmo que o valor do atributo fosse do tipoNone
e isso causariaset
falha no meu comando ElementTree .Se o valor do atributo fosse do tipo
None
,getattr
também o retornaria, o que causariaset
falha no meu comando ElementTree .Eu uso o seguinte método para cuidar desses casos agora:
É quando e como eu uso
getattr
.fonte
Outro uso do getattr () na implementação de uma instrução switch no Python. Ele usa a reflexão para obter o tipo de caso.
fonte
setattr ()
Usamos setattr para adicionar um atributo à nossa instância de classe. Passamos a instância da classe, o nome do atributo e o valor.
getattr ()
Com getattr , recuperamos esses valores
Por exemplo
fonte
Eu acho que este exemplo é auto-explicativo. Ele executa o método do primeiro parâmetro, cujo nome é fornecido no segundo parâmetro.
fonte
Também está esclarecendo em https://www.programiz.com/python-programming/methods/built-in/getattr
A idade é: 23
A idade é: 23
O sexo é: Masculino
AttributeError: o objeto 'Person' não tem atributo 'sex'
fonte
Eu tentei no Python2.7.17
Alguns dos colegas já responderam. No entanto, tentei chamar getattr (obj, 'set_value') e isso não executou o método set_value, então mudei para getattr (obj, 'set_value') () -> Isso ajuda a invocar o mesmo.
Código de exemplo:
Exemplo 1:
fonte