2013-06-25 6 views
4

나는 초기화 비용이 높은 공유 리소스를 가지고 있으므로 시스템을 통해 액세스하려고합니다 (기본적으로 일부 계측에는 사용되므로 가벼워 야합니다). 그래서 설치와 접근을 관리하는 모듈을 만들었습니다. 그것은 게으른 초기화 리소스를 모듈 전역 변수에 저장합니다. 그런 다음 시스템 전체에서이 모듈의 기능을 사용하여 자원을 조작합니다.
- 이제 리소스를 다시 초기화해야하는지 (또는 얼마나 자주) 해야할지 궁금합니다.
- 개체가 CPython에서 가비지 컬렉터 (또는 더 나은) 0 참조 횟수를 수집하지만, 모듈이 현재 실행되고 있지 않더라도 참조로 계산 된 모듈에 저장된다는 것을 알고 있습니까?Python : 모듈 전역 변수의 수명

코드 예제 : 여기에는 _connect()가 느린 모듈이 있습니다. 내 시스템에서 report_safely()를 사용하여 _connect()를 가능한 한 드물게 호출하려고합니다.

__metrics = None 


def _connect(): 
    global __metrics 

    client = SomeSlowToSetUpClient() 
    __metrics = SomeMetrics(client) 
    client.connect() 


def report_safely(): 
     if not __metrics: 
      _connect() 

     __metrics.execute_lightweight_code() 
+0

하나의 질문은 기본적으로 ** 처음 연결 후 **이 문제가 항상 ** 연결되어 있는지 확인하는 것이 좋습니다. – voithos

+0

글쎄, 이건 단지 UDP 패킷을 서버에 보내고 있기 때문에 연결 상태에 문제가없는 것 같니? – Zakum

답변

8

더 이상 참조되지 않는 개체는 실제로 가비지 수집됩니다 (참조 횟수가 0으로 떨어지면 자동으로 삭제됩니다).

그러나 global 모듈은 참조 카운트가 0으로 떨어지지 않습니다. 모듈 객체 (네임 스페이스)를 가져 오면 sys.modules 매핑에 있습니다. 네임 스페이스 자체가 개체를 참조합니다.

즉, 모듈 네임 스페이스에서 모듈 이름 공간을 삭제하거나 (del sys.modules['yourmodule']) 모듈을 삭제하거나 파이썬 스크립트를 종료 할 때까지 개체가 영원히 지속됩니다.

+0

그건 좋은 소리. 마르티네 감사합니다! 그러나 지금 나는 어떤 스크립트가 의미하는지 궁금해. 컨텍스트는 장고 (Django) 응용 프로그램이며이 항목을 가져 오는 모듈은 (샐러리) 작업자 스레드에서 실행됩니다. 이는 모듈이 각 작업자 스레드 종료시 실행되거나 부모의 수명이 다했음을 의미합니까? 내 말은 ... 내가 어버이 산란 어딘가에 가져올 수있는 스레드,하지만 그건 약간 재키 소리. – Zakum

+0

@ Zakum : 셀러리 작업자가 코드를 한 번만 가져오고 스레드로 작업을 실행합니다. –

+0

... 셀러리가 돌아가고있는 한 나는 좋다. 그랜드, 고마워! (이 경우에는 몇 시간 동안이나 의견을 열어 두지 만 허용 된 답변에 대해서는 강한 주장을하는 것처럼 보입니다) – Zakum

0

전역을 포함하는 모듈이 실행 시작부터 끝까지 범위에 포함되면 전역 변수가됩니다. 클래스 인스턴스를 사용하는 것이 더 깔끔할 수도 있습니다.

+0

싱글 톤 (Singleton)과 같은 자바도 제 첫 번째 아이디어였습니다. 그러나 그 점에서 저는 @classmethods와 classvariables 만 가지고 있었기 때문에 그럴 수 없었습니다. 또한, 가비지 수집에 대한 동일한 질문이 Singleton 클래스에서 발생합니다. – Zakum