Python получает исходное имя списка из функции класса

#python #variables #global

#python #переменные #глобальный

Вопрос:

Спасибо за помощь. Как я могу получить доступ к имени глобальной переменной при импорте класса? У меня есть несколько списков чисел с именами переменных

 apples=[1,2,3]
bananas=[4,5,6]
coconuts=[7,8,9]
 

Я хочу вызвать функцию вспомогательного класса, которую я вызываю из внешнего файла с именем funk.py для того, чтобы поместить их в pandas DataFrame ()

 class funk:
def __init__(self,*args):
data=pd.DataFrame()
###if apples is in the list
data['Apples']=apples
###if bananas is in the list
data['Bananas']=bananas
###if bananas is in the list
data['Bananas']=bananas
###if bananas is in the list
data['Bananas']=bananas
###if coconuts is in the list
data['Coconuts']=coconuts
return data
 

а затем вызовите funk.funk(apples,bananas)

Я не знаю, как ссылаться на отдельные входные данные, списки по их первоначальному имени. Я мог бы добавить отдельный список, который возможен явно в аргументах функции, но это кажется почти излишним.

Ответ №1:

Не рекомендуется делать все так, как вы просите, поскольку оно не является явным, может быть сложным для отладки, одно значение может иметь несколько имен переменных, и, вероятно, оно не будет работать должным образом, если вызывается внутри функции (вам следует избегать полагаться на то, что вещи являются глобальными).

Также вы, вероятно, имеете в виду использовать функцию вместо класса. Вы не можете возвращать значения из конструктора класса, как показано в вашем коде, и, поскольку вы не используете переменную self, у вас, вероятно, нет никакого состояния для отслеживания между вызовами методов и, следовательно, на самом деле не нужен класс.

Для вас было бы лучше использовать функцию с аргументами ключевого слова. Также вы намеренно хотели использовать заглавные буквы в именах столбцов?

 import pandas as pd
def funk(**kwargs):
    data=pd.DataFrame()
    for kw,val_list in kwargs.items():
        data[kw.capitalize()] = val_list
    return data
apples=[1,2,3]
bananas=[4,5,6]
df=funk(apples=apples,bananas=bananas, coconuts=[7,8,9])
 

Если вы действительно действительно хотели сделать это так, как вы просили, и переменные действительно были в глобальном пространстве модулей, тогда вы могли бы сделать следующее:

 import pandas as pd
def funk(*args):
    args_ids = set([id(arg) for arg in args])
    data = pd.DataFrame()
    for name,value in globals().items():
        if id(value) in args_ids:
            data[name.capitalize()] = value
    return data
apples=[1,2,3]
bananas=[4,5,6]
df=funk(apples,bananas)
 

Если вы действительно хотели сказать, что вызываете контекст вместо глобальных значений, скажем, если вы хотите, чтобы это работало внутри функции, тогда вы могли бы сделать:

 import inspect, pandas as pd

def funk(*args):
    args_ids = set([id(arg) for arg in args])
    data = pd.DataFrame()
    for name,value in inspect.stack()[1].frame.f_locals.items():
        if id(value) in args_ids:
            data[name.capitalize()] = value
    return data
apples=[1,2,3]
bananas=[4,5,6]
df=funk(apples,bananas)
 

Теперь одна из причин, по которой последние два решения являются плохими идеями, заключается в следующем:

 apples=[1,2,3]
bananas=[4,5,6]
coconuts = bananas
df=funk(apples,bananas) 
 

Этот фрейм данных фактически будет содержать три столбца: яблоки, бананы и кокосы, потому что объект coconuts был в списке аргументов, поскольку имена переменных bananas и coconuts относятся к одному и тому же объекту. Принятие только одного из них не является решением, потому что код не будет знать, какое имя переменной, bananas или coconuts было использовано для его вызова — у вас будет предположение 50/50. Это можно обойти, фактически проверив исходный код вызова и выполнив поиск имен, переданных функции. Это выполнимо, но мы становимся смешными. Это не то, как язык предназначен для использования, и в вашем коде, скорее всего, будут ошибки. Вы должны просто использовать подход с ключевыми словами arguments в верхней части этого ответа, что является приемлемым способом ведения дел.

Ответ №2:

Что-то вроде этого

 import filename
class funk:
    def __init__(self,*args):
        data=pd.DataFrame()
        ###if apples is in the list
        data['Apples']= filename.apples
        ###if bananas is in the list
        data['Bananas']= filename.bananas
        ###if coconuts is in the list
        data['Coconuts']= filename.coconuts
        self.data = data
 

Комментарии:

1. __init__ всегда должно возвращаться None .

2. Упс, не заметил, что это просто скопировано из вопроса.