현재 모듈에서 setattr ()을 어떻게 호출합니까?


140

현재 모듈에서 변수를 설정 object하기 위해 함수에 첫 번째 매개 변수 " "를 전달하려면 무엇을해야 setattr(object, name, value)합니까?

예를 들면 다음과 같습니다.

setattr(object, "SOME_CONSTANT", 42);

다음과 같은 효과를줍니다 :

SOME_CONSTANT = 42

이 줄을 포함하는 모듈 내에서 (올바른 object).

모듈 수준에서 여러 값을 동적으로 생성하고 모듈 수준 __getattr__에서 정의 할 수 없으므로 이것이 내 폴백입니다.

답변:


220
import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

또는, 사용하지 않고 setattr(질문을 깨뜨리지 만 동일한 실제 목적을 충족시킵니다 .-) :

globals()[name] = value

참고 : 모듈 범위에서 후자는 다음과 같습니다.

vars()[name] = value

이것은 좀 더 간결하지만 함수 내에서 작동하지 않습니다 ( vars()해당 범위의 변수를 제공합니다 : 전역 범위에서 호출 될 때의 모듈 변수, 그리고 R / W를 사용하는 것이 좋습니다, 그러나 함수의 함수에서 호출 될 때 변수를 호출 한 다음 R / O로 처리해야합니다 .Python 온라인 문서는이 특정 차이점에 대해 약간 혼란 스러울 수 있습니다).


9
문서는 vars () 수정에 대한 경고를 표시합니다. docs.python.org/library/functions.html#vars . 언제이 작업을 수행해도 되나요?
unutbu

2
@ ~ unutbu, 나는 그것이 실제로 "괜찮다"고 말하지는 않지만 vars()함수 내부가 아닌 모듈 수준 범위에서 호출 할 때 작동 합니다.
Mike Graham

4
vars()globals()모듈 범위에서 (따라서 수정 가능한 실제 dict를 반환) locals()함수 범위에서 (따라서 절대로 수정 불가능한 의사를 반환)와 같습니다. 나는 vars()모듈 범위에서 3 개의 문자, 한 음절을 저장하기 때문에 그 동의어 globals();-)를 절약하므로 모듈 범위에서 사용합니다 .
Alex Martelli

14
그렇습니다. 파이썬 컴파일러가 수행하는 가장 중요한 단일 최적화를 파괴했을 것입니다. 함수의 지역 변수는 받아쓰기 가 아니며 , 값이 꽉 찬 벡터에 있으며, 각 지역 변수 액세스는 해당 벡터의 색인을 사용하지 않습니다. 이름 조회. 최적화를 물리 치고, 당신이 존재하고자하는 dict을 강요하려면 함수를 시작하십시오 exec '': 각 방법에 몇 개의 실질적인 루프가있는 함수 시간. 파이썬의 성능 에이 핵심 최적화의 중요성을 알 수 있습니다.
Alex Martelli

3
@ msw, 나는 당신이 "실용성이 순도를 능가합니다";-)를 잊어 버린 것 같아요.
Alex Martelli

6

모듈 내에서 모듈 범위 변수를 설정해야하는 경우 무엇이 문제 global입니까?

# my_module.py

def define_module_scoped_variables():
    global a, b, c
    a, b, c = 'a', ['b'], 3

그러므로:

>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']

1
그래, 나는 항상 "항상"은 "파이썬을 배우고있는 지난 몇 달"로 정의되어있다 global but not really. 모듈 네임 스페이스보다 오래된 역사적인 유적 일 수 있습니다.
msw

1
원래 질문은 이름이 문자열로 제공되는 속성을 설정하는 방법을 묻는 것입니다 (현재 검색중인 것과 동일). 그래도 도움이되지 않습니다.
Curt

6

Python 3.7에서는 __getattr__모듈 수준에서 사용할 수 있습니다 ( 관련 답변 ).

PEP 562 당 :

def __getattr__(name):
    if name == "SOME_CONSTANT":
        return 42
    raise AttributeError(f"module {__name__} has no attribute {name}")

-1
  1. 당신은하지 않을 것입니다. 당신은 할 것globals()["SOME_CONSTANT"] = 42
  2. 당신은하지 않을 것입니다. 모듈이 아닌 다른 곳에 동적으로 생성 된 컨텐츠를 저장합니다.

그러나 SOME_CONSTANT런타임에 계산되는 것은 정확히 일정하지 않습니다. 그리고 만약 globals()당신이 사용할 수 없다면, 당신은 그것의 속성을 수정하기 위해 다른 모듈에 도달해야합니다; 사람들이 궁금해 할 수밖에 없습니다.
msw

3
상수와 가변은 상호 배타적입니다. 일정하고 동적으로 생성되지 않습니다. 내가 생성하는 값은 항상 동일하며 추가 "상수"를 기반으로 결정되어 내 산술 및 입력을 절약합니다.
Matt Joiner
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.