programing

Python에서 모듈 전체 변수를 만드는 방법은 무엇입니까?

kingscode 2023. 1. 22. 22:42
반응형

Python에서 모듈 전체 변수를 만드는 방법은 무엇입니까?

모듈 내부에서 글로벌 변수를 설정하는 방법이 있습니까? 있는 Python "Python"을 "Python" "Python" "Python" "Python" "Python" "Python" "Python" "Python" "Python"__DBNAME__존재하지 않았습니다.

...
__DBNAME__ = None

def initDB(name):
    if not __DBNAME__:
        __DBNAME__ = name
    else:
        raise RuntimeError("Database name has already been set.")
...

모듈을 다른 파일로 Import한 후

...
import mymodule
mymodule.initDB('mydb.sqlite')
...

트레이스백은 다음과 같습니다.

...UnboundLocalError: 할당 전에 로컬 변수 'DBNAME'이(가)

좋은 생각 있어요? 친구의 추천에 따라 모듈을 사용하여 싱글톤을 설정하려고 합니다.

무슨 일이 일어나고 있는지 말해줄게.

첫째, Python이 가진 유일한 글로벌 변수는 모듈 범위 변수입니다.진정으로 글로벌한 변수는 만들 수 없습니다.특정 범위에서 변수를 만드는 것밖에 할 수 없습니다.(Python 인터프리터 내에서 변수를 만들고 다른 모듈을 Import하면 변수는 가장 바깥쪽 범위에 속하므로 Python 세션 내에서 글로벌합니다.)

module-global 변수를 작성하려면 이름만 할당하면 됩니다.

foo.py 라고 하는 파일에, 다음의 행이 포함되어 있다고 가정합니다.

X = 1

이제 Import를 상상해 보십시오.

import foo
print(foo.X)  # prints 1

중 합니다.Python의 기본값은 함수 변수가 로컬이라고 가정하는 것입니다. 가만 a a a a a a a a a a를 붙이면 됩니다.globaldiscription을 합니다.

def initDB(name):
    global __DBNAME__  # add this line!
    if __DBNAME__ is None: # see notes below; explicit test for None
        __DBNAME__ = name
    else:
        raise RuntimeError("Database name has already been set.")

한 「 」, 「 」, 「 」, 「 」가 if not __DBNAME__빈 true로 에 적절합니다따라서 실제 이름은 true.test를 합니다. 숫자 수 만 말할 수 .if not variablename이에 대해 해야 합니다.Noneis 해서 명료하게 했습니다.None테스트에 대한 입니다. 에 대한 명시적 테스트None절대 틀리지 않기 때문에 디폴트로 사용하고 있습니다.

마지막으로, 다른 사람들이 이 페이지에서 언급했듯이, 두 개의 선행 밑줄은 Python에 대해 변수를 모듈에 대해 "개인"으로 만들고 싶다는 신호를 보냅니다. import * from mymodule에 두 이 있는 . Python은 다음과 그냥 하면 돼요import mymodule 다음 '아까운명하다.dir(mymodule)되고, 「프라이빗」변수를 했을 경우는, 「프라이빗」변수가 표시됩니다.mymodule.__DBNAME__Python은 신경 쓰지 않고 참고만 할 것이다.두 개의 선행 밑줄은 모듈 사용자에게 해당 이름을 자신의 값에 다시 바인딩하지 않는 것이 좋다는 주요 단서가 됩니다.

에서는 Python을 하지 않는 것이 로 여겨지고 .import *, 하려면 , 음, 음, 음, 다, 다, ness, ness, ness, ness, ness, ness, ness, ness, ness, ness, ness, ness, ness, ,, ,, ness, ness, 를 사용합니다.mymodule.something Import와 같은 from mymodule import something.

편집: 만약 어떤 이유로, 당신이 매우 오래된 버전의 Python에서 이와 같은 작업을 해야 한다면,global키워드에는 간단한 회피책이 있습니다.모듈 글로벌 변수를 직접 설정하는 대신 모듈 글로벌레벨에서 가변형을 사용하여 값을 저장합니다.

함수에서 글로벌 변수 이름은 읽기 전용이므로 실제 글로벌 변수 이름을 다시 바인딩할 수 없습니다.(함수 내의 변수 이름에 할당하면 함수 내의 로컬 변수 이름에만 영향을 줍니다).그러나 이 로컬 변수 이름을 사용하여 실제 글로벌 개체에 액세스하고 그 안에 데이터를 저장할 수 있습니다.

'어울리다'를 사용할 수 요.list이치노

__DBNAME__ = [None] # use length-1 list as a mutable

# later, in code:  
if __DBNAME__[0] is None:
    __DBNAME__[0] = name

A dict, 단순한 할 수 .그러나 가장 편리한 것은 클래스 인스턴스입니다.그냥 단순한 클래스를 사용할 수 있습니다.

class Box:
    pass

__m = Box()  # m will contain all module-level values
__m.dbname = None  # database name global in module

# later, in code:
if __m.dbname is None:
    __m.dbname = name

(데이터베이스 이름 변수를 대문자화할 필요는 없습니다).

저는 그냥 사용하는 통사당이 좋아요.__m.dbname__m["DBNAME"]내 생각에는 그것이 가장 편리한 해결책인 것 같다.그...dict솔루션도 정상적으로 동작합니다.

dict 가능 할 수 , 한 식별자 할 수 있는 는, 「유효한 식별자」라고 하는 할 수 .Box상기에 기재되어 있습니다.

모듈 레벨 변수에 액세스하여 모듈 레벨 변수에 대한 명시적 액세스


요컨대:여기서 설명하는 기술은 변수의 범위를 명시적으로 지정하기 위해 인위적인 도우미 개체가 생성되지 않는다는 점을 제외하고Steveha의 답변과 동일합니다.대신 모듈 오브젝트 자체에 변수 포인터가 주어지기 때문에 모든 장소에서 액세스 시 명시적인 스코핑이 제공됩니다. (로컬 기능 범위의 할당과 같습니다).

현재 인스턴스가 아닌 현재 모듈셀프라고 생각해 주세요!

# db.py
import sys

# this is a pointer to the module object instance itself.
this = sys.modules[__name__]

# we can explicitly make assignments on it 
this.db_name = None

def initialize_db(name):
    if (this.db_name is None):
        # also in local function scope. no scope specifier like global is needed
        this.db_name = name
        # also the name remains free for local use
        db_name = "Locally scoped db_name variable. Doesn't do anything here."
    else:
        msg = "Database is already initialized to {0}."
        raise RuntimeError(msg.format(this.db_name))

모듈은 캐시되므로 Import는 1회뿐이므로 Import할 수 있습니다.db.py원하는 수의 클라이언트에서 동일한 범용 상태를 조작할 수 있습니다.

# client_a.py
import db

db.initialize_db('mongo')
# client_b.py
import db

if (db.db_name == 'mongo'):
    db.db_name = None  # this is the preferred way of usage, as it updates the value for all clients, because they access the same reference from the same module object
# client_c.py
from db import db_name
# be careful when importing like this, as a new reference "db_name" will
# be created in the module namespace of client_c, which points to the value 
# that "db.db_name" has at import time of "client_c".

if (db_name == 'mongo'):  # checking is fine if "db.db_name" doesn't change
    db_name = None  # be careful, because this only assigns the reference client_c.db_name to a new value, but leaves db.db_name pointing to its current value.

추가적인 보너스로서 나는 그것이 피톤스의 명시적 정책이 암묵적 정책보다 더 낫기 때문에 전반적으로 꽤 피톤적인 것을 발견한다.

스티브하의 답변은 저에게 도움이 되었지만, 중요한 요점을 빠뜨렸습니다.함수 내의 변수에 액세스만 하고 할당하지 않는 경우 global 키워드는 필요하지 않습니다.

global 키워드를 지정하지 않고 변수를 할당하면 Python은 새 로컬 변수를 만듭니다. 모듈 변수의 값은 함수 안에 숨겨집니다.함수 내에 모듈 변수를 할당하려면 global 키워드를 사용합니다.

Python 2.7의 Pylint 1.3.1은 var를 할당하지 않으면 NOT using global을 적용합니다.

module_var = '/dev/hello'

def readonly_access():
    connect(module_var)

def readwrite_access():
    global module_var
    module_var = '/dev/hello2'
    connect(module_var)

이를 위해서는 변수를 글로벌로 선언해야 합니다.단, 글로벌 변수에는 모듈 외부에서module_name.var_name을 사용법

global __DBNAME__

당신은 미묘한 장난에 속고 있어요.python 함수 내에서 모듈 수준 변수를 다시 할당할 수 없습니다.내 생각에 이건 사람들이 실수로 함수 안에서 물건을 다시 할당하는 것을 막기 위해서인 것 같아요.

모듈 이름 공간에 액세스할 수 있습니다. 재할당을 시도하지 마십시오.함수가 무언가를 할당하면 자동으로 함수 변수가 되고 python은 모듈 네임스페이스에서 검색되지 않습니다.

다음 작업을 수행할 수 있습니다.

__DB_NAME__ = None

def func():
    if __DB_NAME__:
        connect(__DB_NAME__)
    else:
        connect(Default_value)

다시 쓸 수는 요.__DB_NAME__함수의 내부에 있습니다.

하나의 회피책:

__DB_NAME__ = [None]

def func():
    if __DB_NAME__[0]:
        connect(__DB_NAME__[0])
    else:
        __DB_NAME__[0] = Default_value

.__DB_NAME__내용을 수정하고 있을 뿐입니다.

언급URL : https://stackoverflow.com/questions/1977362/how-to-create-module-wide-variables-in-python

반응형