2016-08-23 8 views
-5

가 개발자 안녕하세요,전역 변수 작동하지 파이썬

i는 사용자의 입력을 받아 아래의 예제 코드에서와 같이 입력에 따라 클래스를 초기화 코드를 쓰고 있어요 :

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()") 

하지만 등을 I

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 
012 :이 오류가 계속

다음과 같은 코드를 실행

아무도 도와 줄 수 있습니까? 이런 식으로

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

, 당신이 당신의 세계에 대해 부동 원치 않는 cruft에의 전체 무리가 없습니다 :

+2

변수가 이미 전역 범위에 있어야합니다. 또한, 이것은 끔찍한 생각입니다. 게다가, 당신은'x'의 인스턴스를 만들려고합니다,하지만 당신의 클래스는'X'라고합니다. –

+0

왜 그렇게 나쁜가요? @MorganThrapp –

+1

가능한 변수 수를 어떻게 만들 수 있습니까? (http://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables) -in-python) –

답변

0

당신이 이 방법을 실행 func2 인스턴스화를 가진 더 나을 것 같아 네임 스페이스와 신뢰할 수없는 일을 끝내지 않아 exec. 또한, exec을 입력하면 함수 안에있는 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 키가있는 글로벌 사전이 있습니다.