복붙노트

[PYTHON] `import __main__`을 사용하는 것이 좋은 습관입니까?

PYTHON

`import __main__`을 사용하는 것이 좋은 습관입니까?

상대적으로 큰 Python 응용 프로그램을 작성 중이며 여러 다른 모듈에서 전역 변수로 액세스 할 수 있도록 유지하려는 몇 가지 리소스가 있습니다. 이 값은 버전 번호, 버전 날짜, 전역 구성 및 리소스에 대한 정적 경로와 같은 것들입니다. 전체 환경을 필요로하지 않고 디버그 모드에서 내 응용 프로그램을 실행할 수 있도록 명령 줄 옵션으로 설정되는 DEBUG 플래그도 포함했습니다.

필자가 가져온 값은 프로그램을 실행하는 동안 변경되지 않는 값을 보장하기 위해주의를 기울였습니다. 그리고 이러한 변수를 건드리지 않아야하는 전역 상수 변수로 문서화했습니다. 내 코드는 본질적으로 좋아 보인다.

# Main.py
import wx
from gui import Gui

DEBUG = False
GLOBAL_CONFIG = None
VERSION = '1.0'
ICON_PATH = 'some/path/to/the/app.ico'

def main():
    global DEBUG, GLOBAL_CONFIG

    # Simplified
    import sys
    DEBUG = '--debug' in sys.argv

    GLOBAL_CONFIG = load_global_config()
    # Other set-up for the application, e.g. setting up logging, configs, etc

    app = wx.App()
    gui = Gui()
    app.MainLoop()

if __name__ == '__main__':
    main()
# gui.py
import wx
from __main__ import DEBUG, GLOBAL_CONFIG, ICON_PATH

import controller


class Gui(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)

        icon = wx.Icon(ICON_PATH, wx.BITMAP_TYPE_ICO)
        self.SetIcon(icon)

        # Always make a copy so we don't accidentally modify it
        conf = GLOBAL_CONFIG.copy()
        self.controller = controller.Controller(conf)

        # More setup, building the layout, etc
# controller.py
from __main__ import DEBUG

import logging
log = logging.getLogger('controller')

class Controller(object):
    def __init__(self, conf):
        if DEBUG:
            log.info("Initializing controller in DEBUG mode")
        self.conf = conf
        # Other setup ...

이것은 분명히 내 응용 프로그램이 실제로 가지고있는 것에서 벗어나 오류 처리, 문서화 및 기본적으로 모든 구현 세부 사항을 무시합니다.

지금, 나는 이것이 나쁜 생각이라고 말한 것을 보았습니다. 그러나 이유에 대한 설명이 없습니다. "python import __main__"변종에 대한 인터넷 검색 때 대부분의 결과는 __name__ == '__main__'이 무엇인지에 대한 질문이므로이 주제에 대한 확실한 정보를 찾기가 어렵습니다. 지금까지 나는 그것에 문제가 없었고, 실제로 실제로 편리했습니다.

이것이 훌륭한 파이썬 실습으로 간주 되는가? 아니면이 디자인을 피해야하는 이유가 있는가?

해결법

  1. ==============================

    1.나는이 패턴의 회피를 처방 할 수있는 두 가지 주요한 (하하) 이유가 있다고 생각한다.

    나는이 패턴의 회피를 처방 할 수있는 두 가지 주요한 (하하) 이유가 있다고 생각한다.

    응용 프로그램을 완벽하게 제어 할 수 있고 기능에 대한 또 다른 진입 점이나 다른 용도가 없을 것이며 모호성에 신경 쓰지 않는다고 생각하면 왜 __main__에서 가져온 이유가 무엇인지 생각하지 않습니다. foo 패턴이 나쁩니다. 나는 그것을 개인적으로 좋아하지 않지만, 다시 말하면 기본적으로 위의 두 가지 이유 때문입니다.

    보다 견고한 / 개발자 친화적 인 솔루션은 이와 같은 수퍼 글로벌 변수를 담을 수있는 특수 모듈을 만드는 것입니다. 그런 다음 모듈을 가져 와서 설정이 필요할 때마다 module.VAR을 참조 할 수 있습니다. 기본적으로 수퍼 글로벌 런타임 구성을 저장할 특수 모듈 네임 스페이스를 만드는 것입니다.

    # conf.py (for example)
    # This module holds all the "super-global" stuff.
    def init(args):
        global DEBUG
        DEBUG = '--debug' in args
        # set up other global vars here.
    

    다음과 같이 사용하면됩니다.

    # main.py
    import conf
    import app
    
    if __name__ == '__main__':
        import sys
        conf.init(sys.argv[1:])
    
        app.run()
    
    # app.py
    import conf
    
    def run():
        if conf.DEBUG:
            print('debug is on')
    

    conf import DEBUG보다는 conf.DEBUG를 사용하십시오. 이 구조는 프로그램의 수명 동안 변수를 변경할 수 있으며 변경 사항을 다른 곳에서 반영하도록 할 수 있음을 의미합니다 (명백히 단일 스레드 / 프로세스라고 가정).

    또 다른 단점은 이것이 매우 일반적인 패턴이므로 다른 개발자도 쉽게 인식 할 수 있습니다. settings.py는 일반적으로 런타임 매개 변수의 네임 스페이스가 아닌 정적 객체의 묶음이므로 특정 이름은 사용하지 않았지만 다양한 인기있는 앱 (예 : django)에서 사용하는 settings.py 파일과 쉽게 비교할 수 있습니다. 위에 설명 된 구성 네임 스페이스 모듈의 다른 좋은 이름은 예를 들어 런타임 또는 params 일 수 있습니다.

  2. ==============================

    2.그렇게하기 위해서는 PEP8을 위반해야합니다.

    그렇게하기 위해서는 PEP8을 위반해야합니다.

    gui.py가 __main __. DEBUG를 성공적으로 import하려면 gui를 import하기 전에 DEBUG의 값을 설정해야합니다.

  3. from https://stackoverflow.com/questions/24023601/is-it-good-practice-to-use-import-main by cc-by-sa and MIT license