Este tópico discute como obter o nome de uma função como uma string no Python: Como obter o nome de uma função como uma string?
Como posso fazer o mesmo para uma variável? Ao contrário de funções, as variáveis Python não têm o __name__
atributo
Em outras palavras, se eu tiver uma variável como:
foo = dict()
foo['bar'] = 2
Eu estou procurando uma função / atributo, por exemplo retrieve_name()
, para criar um DataFrame no Pandas a partir desta lista , onde os nomes das colunas são dados pelos nomes dos dicionários reais:
# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [retrieve_name(d) for d in list_of_dicts]
pip3 install python-varname==0.1.5
; importado usandofrom varname import nameof
test = {}
print(varname.nameof(test))
for i in [0]:
print(varname.nameof(test))
a primeira impressão fornecetest
, a impressão no loop aumentaVarnameRetrievingError: Callee's node cannot be detected.
v0.2.0
Os únicos objetos no Python que têm nomes canônicos são módulos, funções e classes e, é claro, não há garantia de que esse nome canônico tenha algum significado em qualquer espaço de nome após a função ou classe ter sido definida ou o módulo importado. Esses nomes também podem ser modificados após a criação dos objetos, para que eles nem sempre sejam particularmente confiáveis.
O que você deseja fazer não é possível sem percorrer recursivamente a árvore de objetos nomeados ; um nome é uma referência unidirecional para um objeto. Um objeto Python comum ou de variedade de jardim não contém referências a seus nomes. Imagine se todos os números inteiros, todos os ditados, todas as listas e todos os booleanos precisassem para manter uma lista de strings que representassem nomes que se referiam a ele! Seria um pesadelo de implementação, com pouco benefício para o programador.
fonte
__name__
sempre pode ser modificado, o que significa que o nome "canônico" pode não ser um nome que possa ser usado para obter o objeto (por exemplo, ao criar classes dinamicamente).Mesmo se os valores das variáveis não apontarem para o nome, você terá acesso à lista de todas as variáveis atribuídas e seu valor, por isso estou surpreso que apenas uma pessoa tenha sugerido um loop por lá para procurar seu nome de var.
Alguém mencionou nessa resposta que talvez você precise percorrer a pilha e verificar os locais e globais de todos
foo
, mas sefoo
estiver atribuído no escopo em que você está chamando essaretrieve_name
função, você pode usarinspect
o comando 'scurrent frame
para obter todas essas variáveis locais .Minha explicação pode ser um pouco exagerada (talvez eu devesse ter usado um "foo" menos palavras), mas aqui está como ficaria no código ( observe que, se houver mais de uma variável atribuída ao mesmo valor, você obtenha os dois nomes de variáveis ):
Se você está chamando essa função de outra função, algo como:
E você deseja que, em
baz
vez debar
, apenas precise voltar um escopo ainda mais. Isso pode ser feito adicionando um extra.f_back
nacaller_local_vars
inicialização.Veja um exemplo aqui: ideone
fonte
import hooks
,ironpython
ejython
a, b = 2, 2
,retrieve_name(a)
eretrieve_name(b)
irão devolver['a', 'b']
ou['b', 'a']
true
para umais
comparaçãodef foo(bar): retrieve_name(bar)
, sempre retornará a barra, mas e se você quiserfoo(baz)
retornarbaz
) em vez debar
?callers_local_vars
para ir um escopo mais para trás, para analisar o escopo de qualquer coisa que esteja chamandofoo
. Mude a linha para serinspect.currentframe().f_back.f_back.f_locals.items()
(observe o extraf_back
).Com o Python 3.8, pode-se simplesmente usar o recurso de depuração de string f:
fonte
f'{foo=}'.split('=')[0].split('.')[-1]
No python3, essa função obterá o nome mais externo da pilha:
É útil em qualquer lugar do código. Atravessa a pilha invertida procurando a primeira correspondência.
fonte
retrieve_name(SomeClass.some_attribute)
, não funciona. Você pode ajudar ainda mais nisso?stop_on_error
Não acredito que isso seja possível. Considere o seguinte exemplo:
O
a
eb
apontam para o mesmo objeto, mas o objeto não pode saber quais variáveis apontam para ele.fonte
É usado assim:
fonte
name(variable=variable)
saída de vontade['variable']
, e usandoname(variable=another_variable)
irá não saída['another_variable']
, mas sim['variable']
.>>> a = []
>>> b = a
>>> name(a=b)
['a']
>>> name(b=a)
['b']
`Aqui está uma abordagem. Eu não recomendaria isso por nada importante, porque será bastante quebradiço. Mas isto pode ser feito.
Crie uma função que use o
inspect
módulo para encontrar o código-fonte que o chamou. Em seguida, você pode analisar o código-fonte para identificar os nomes das variáveis que deseja recuperar. Por exemplo, aqui está uma função chamadaautodict
que pega uma lista de variáveis e retorna um dicionário mapeando nomes de variáveis para seus valores. Por exemplo:Daria:
Inspecionar o código fonte em si é melhor do que pesquisar na
locals()
ouglobals()
porque a última abordagem não informa quais variáveis são as desejadas.De qualquer forma, aqui está o código:
A ação acontece na linha com
inspect.getouterframes
, que retorna a string no código que chamouautodict
.A desvantagem óbvia para esse tipo de mágica é que ela faz suposições sobre como o código-fonte é estruturado. E, é claro, não funcionará se for executado dentro do intérprete.
fonte
Eu escrevi a feitiçaria de pacotes para fazer esse tipo de mágica de maneira robusta. Você pode escrever:
e passe isso para o construtor de quadro de dados. É equivalente a:
fonte
Se você quisesse escrever sua própria função, isso poderia ser feito para que você pudesse procurar uma variável definida em locais e depois verificar globais. Se nada for encontrado, você poderá comparar no id () para ver se a variável aponta para o mesmo local na memória.
Se sua variável estiver em uma classe, você poderá usar className. dict .keys () ou vars (self) para ver se sua variável foi definida.
fonte
locals
eglobals
... e corre o risco de errar o nome, se não existir. É uma tonelada de trabalho para nenhum ganho útil real.Em Python, o
def
eclass
palavras-chave vincularão um nome específico ao objeto que definem (função ou classe). Da mesma forma, os módulos recebem um nome em virtude de serem chamados de algo específico no sistema de arquivos. Nos três casos, há uma maneira óbvia de atribuir um nome "canônico" ao objeto em questão.No entanto, para outros tipos de objetos, esse nome canônico pode simplesmente não existir . Por exemplo, considere os elementos de uma lista. Os elementos da lista não são nomeados individualmente e é inteiramente possível que a única maneira de se referir a eles em um programa seja usando índices de lista na lista que o contém. Se essa lista de objetos tiver sido passada para sua função, você não poderá atribuir identificadores significativos aos valores.
Python não salva o nome no lado esquerdo de uma atribuição no objeto atribuído porque:
Assim, por exemplo, as funções definidas usando
lambda
sempre terão o "nome"<lambda>
, em vez de um nome de função específico.A melhor abordagem seria simplesmente pedir ao chamador que passasse uma lista (opcional) de nomes. Se digitar o
'...','...'
é muito complicado, você pode aceitar, por exemplo, uma única string contendo uma lista de nomes separados por vírgula (comonamedtuple
faz).fonte
locals () - Retorna um dicionário que contém as variáveis locais do escopo atual. iterando através deste dicionário, podemos verificar a chave que tem um valor igual à variável definida, apenas extrair a chave fornecerá o texto da variável no formato de string.
from (depois de algumas alterações) https://www.tutorialspoint.com/How-to-get-a-variable-name-as-a-string-in-Python
fonte
Eu acho que é tão difícil fazer isso no Python, pelo simples fato de você nunca saber o nome da variável que está usando. Então, no exemplo dele, você poderia fazer:
Ao invés de:
fonte
apenas outra maneira de fazer isso com base no conteúdo da variável de entrada:
(retorna o nome da primeira variável que corresponde à variável de entrada, caso contrário, Nenhum. É possível modificá-la para obter todos os nomes de variáveis com o mesmo conteúdo que a variável de entrada)
fonte
Esta função imprimirá o nome da variável com seu valor:
fonte
Eu tenho um método e , embora não seja o mais eficiente ... funciona! (e não envolve nenhum módulo sofisticado).
Basicamente, ele compara o seu ID do Variable para globals () IDs Variáveis , em seguida, retorna o nome do jogo.
fonte
Se o objetivo é ajudá-lo a acompanhar suas variáveis, você pode escrever uma função simples que rotule a variável e retorne seu valor e tipo. Por exemplo, suponha que i_f = 3.01 e o arredonde para um número inteiro chamado i_n para usar em um código e, em seguida, precise de uma string i_s que entrará em um relatório.
Isso é impresso na janela em cada chamada para fins de depuração e também gera uma sequência para o relatório escrito. A única desvantagem é que você deve digitar a variável duas vezes sempre que chamar a função.
Eu sou um novato em Python e achei essa maneira muito útil de registrar meus esforços enquanto programa e tento lidar com todos os objetos em Python. Uma falha é que whatis () falha se chama uma função descrita fora do procedimento em que é usada. Por exemplo, int (i_f) era uma chamada de função válida apenas porque a função int é conhecida pelo Python. Você pode chamar whatis () usando int (i_f ** 2), mas se por algum motivo estranho você escolher definir uma função chamada int_squared, ela deverá ser declarada dentro do procedimento em que whatis () é usado.
fonte
Talvez isso possa ser útil:
A função percorre a lista de IDs de valores do escopo global (o namespace pode ser editado), localiza o índice da var ou função desejada / necessária com base em seu ID e, em seguida, retorna o nome da lista de nomes globais com base em no índice adquirido.
fonte
O método a seguir não retornará o nome da variável, mas, usando esse método, você poderá criar um quadro de dados facilmente se a variável estiver disponível no escopo global.
fonte
Para constantes, você pode usar uma enumeração, que suporta a recuperação de seu nome.
fonte
Eu tento obter o nome de inspecionar os locais, mas ele não pode processar var likes a [1], b.val. Depois disso, tive uma nova idéia - obtenha o nome var do código e tento succ! código como abaixo:
fonte
Você pode tentar o seguinte para recuperar o nome de uma função que você definiu (embora não funcione para funções internas):
fonte