2016-08-23 3 views
-5

Здравствуйте разработчики,глобальная переменная не работает питон

я пишу код, который принимает пользовательский ввод и инициализирует класс в зависимости от мощности, как в примере кода ниже:

class X: 
    def __init__(self): 
     return 

    def run(self): 
     print("i am X") 

def func1(cls): 
    exec("global " + cls.lower()) 
    exec(cls.lower() + " = " + cls + "()") 

def func2(mode_to_set): 
    exec(mode_to_set.lower() + ".run()") 

но, как я запустить такой код:

я получаю эту ошибку:

Traceback (most recent call last): 
    File "/Users/noahchalifour/Desktop/test.py", line 16, in <module> 
    func2('X') 
    File "/Users/noahchalifour/Desktop/test.py", line 13, in func2 
    exec(mode_to_set.lower() + ".run()") 
    File "<string>", line 1, in <module> 
NameError: name 'x' is not defined 

Может ли кто-нибудь мне помочь?

+2

Переменная должна уже существовать в глобальном масштабе. Кроме того, это ужасная ИДЕЯ. Кроме того, вы пытаетесь создать экземпляр 'x', но ваш класс называется' X'. –

+0

Почему это так плохо? @MorganThrapp –

+1

Возможный дубликат [Как создать переменное число переменных в Python?] (Http://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables -in-python) –

ответ

0

Похоже, вы бы лучше с func2 Instantiate и запустить метод:

def func2(mode_to_set): 
    globals()[mode_to_set]().run() 

Таким образом, вы не имеете целую кучу хлама плавучего нежелательно о в вашей глобальной пространство имен, и вы не делаете недоверенный exec. Кроме того, exec ing a global Оператор внутри функции не работает (как вы видели) ... exec - это способ выполнения строки, как если бы это был код. Он не является способом отбрасывать динамически созданные заявления в текущую функцию.

1

Намного лучше создать экземпляр класса на основе входных данных пользователя будет использовать «заводской шаблон»:

http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Factory.html

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

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

В принципе «exec» обычно должен быть последним средством. Как правило, более элегантные и безопасные способы решения проблемы.

0

Словари, словари, словари. Ваша программа должна поддерживать контроль над тем, какой код выполняется, вместо того, чтобы позволить пользователю создавать новый код динамически.

classes = {'X': X} 
instances = {} 

def func1(cls): 
    var = cls.lower() 
    instances[var] = classes[cls]() 

def func2(mode_to_set): 
    instances[mode_to_set.lower()].run() 

func1('X') 
func2('X') 

Единственное отличие состоит в том, что вы не имеете глобальную переменную с именем x; у вас есть глобальный словарь с ключом x, который ссылается на ваш экземпляр.

Смежные вопросы