Quero criar um objeto dinâmico (dentro de outro objeto) em Python e depois adicionar atributos a ele.
Eu tentei:
obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')
mas isso não funcionou.
Alguma ideia?
editar:
Estou definindo os atributos de um for
loop que percorre uma lista de valores, por exemplo
params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()
for p in params:
obj.a.p # where p comes from for loop variable
No exemplo acima, gostaria de obter obj.a.attr1
, obj.a.attr2
, obj.a.attr3
.
Eu usei a setattr
função porque não sabia como fazer a obj.a.NAME
partir de um for
loop.
Como eu definiria o atributo com base no valor do p
exemplo acima?
python
class
object
attributes
John
fonte
fonte
a = object()
e precisaobj.a = object()
. Mais uma vez, estou falando do exemplo: no seu código real, um objeto dentro de um objeto pode ser útil.Respostas:
Você pode usar minha receita antiga do Bunch , mas se não quiser criar uma "classe de agrupamento", já existe uma muito simples no Python - todas as funções podem ter atributos arbitrários (incluindo funções lambda). Portanto, o seguinte funciona:
Se a perda de clareza em comparação com a venerável
Bunch
receita está correta, é uma decisão de estilo que, é claro, deixarei para você.fonte
lambda: 23
), de modo que esses especialistas usamlambda
s para esse propósito. presumivelmente não sentiria nada como "um hack". Pessoalmente, não gosto muito delambda
Python - mas isso é uma questão de gosto pessoal.lambda
padrão se encaixa ou não no seu caso de uso pode levar você a perceber que algo que você pensava originalmente como dados é na verdade mais parecido com uma função - ou, em qualquer caso, com um functor.from argparse import Namespace
embora eu desejasse que ele morasse em outro lugar *, por exemplocollection
) - novamente reutilizando um tipo existente, apenas um melhor, e ainda evitando a criação de novos tipos. Mas, não estava lá então :-).O interno
object
pode ser instanciado, mas não pode ter nenhum atributo definido nele. (Eu gostaria que pudesse, para esse propósito exato.) Ele não precisa__dict__
conter os atributos.Eu geralmente apenas faço isso:
Quando posso, dou à
Object
classe um nome mais significativo, dependendo do tipo de dados que estou colocando nela.Algumas pessoas fazem algo diferente, onde usam uma subclasse
dict
que permite que o acesso aos atributos chegue às chaves. (emd.key
vez ded['key']
)Editar : para adicionar à sua pergunta, usar
setattr
é bom. Você simplesmente não pode usarsetattr
emobject()
instâncias.fonte
foo = object()
obras, mas você simplesmente não pode fazer muita coisa com eletype....
ou lambda nunca foi meu favorito, como vômito de texto no meu código. Mas essa idéia é ótima para usar objetos para manter propriedades. Deixa o código mais legível b / c quando vejo lambda, diminuo a velocidade da leitura para 25% enquanto seu caminho faz total sentido! Obrigado.Struct
como o nome da classe para torná-la mais óbvia. Me salvou uma tonelada de digitação["
e"]
, Saúde!Há
types.SimpleNamespace
classe no Python 3.3+ :collections.namedtuple
,typing.NamedTuple
poderia ser usado para objetos imutáveis. PEP 557 - Classes de dados sugere uma alternativa mutável.Para uma funcionalidade mais rica, você pode tentar o
attrs
pacote . Veja um exemplo de uso .fonte
argparse.Namespace
classeattrs
pacote @Roel suporta Python 2.7Existem algumas maneiras de atingir esse objetivo. Basicamente, você precisa de um objeto que seja extensível.
fonte
obj.a = type('', (), {})
O
mock
módulo é basicamente feito para isso.fonte
unittest.Mock
faz parte da biblioteca padrão desde o Python 3.3 ( docs.python.org/3/library/unittest.mock.html )mock
disso. Apenas me parece estranho.Agora você pode fazer (não tenho certeza se é a mesma resposta que evilpie):
fonte
Experimente o código abaixo:
fonte
Você também pode usar um objeto de classe diretamente; ele cria um espaço para nome:
fonte
como dizem os médicos :
Você poderia apenas usar instância de classe fictícia.
fonte
Essas soluções são muito úteis durante o teste. Com base nas respostas de todos os outros, faço isso no Python 2.7.9 (sem staticmethod, recebo um TypeError (método independente ...):
fonte
Quais objetos você está usando? Apenas tentei isso com uma classe de amostra e funcionou bem:
E eu tenho
123
como resposta.A única situação em que vejo essa falha é se você estiver tentando um
setattr
objeto interno.Atualização: A partir do comentário, é uma repetição de: Por que você não pode adicionar atributos ao objeto em python?
fonte
Chegando a esse final do dia, mas aqui está o meu pennyworth com um objeto que contém alguns caminhos úteis em um aplicativo, mas você pode adaptá-lo para qualquer coisa em que você queira um pouco de informação que possa acessar com a notação getattr e dot (sobre o que eu acho que essa pergunta realmente é):
Isso é legal porque agora:
Portanto, isso usa o objeto de função como as respostas acima, mas usa a função para obter os valores (você ainda pode usar
(getattr, x_path, 'repository')
e nãox_path('repository')
se preferir).fonte
Se pudermos determinar e agregar todos os atributos e valores antes de criar o objeto aninhado, poderemos criar uma nova classe que use um argumento de dicionário na criação.
Também podemos permitir argumentos de palavras-chave. Veja este post .
fonte
fonte
De outra maneira, eu vejo, desta maneira:
fonte
class a: pass
fornece toda a energia necessária.