Python 애플리케이션 변경 사항을 인식하는 구성 클래스
15196 단어 pythonprogramming
최소한의 접근
내 응용 프로그램에 구성을 위한 중앙 집중식 위치가 필요한 경우 일반적으로
dict()
개체를 포함하는 전용 파일로 시작합니다.# file: config.py
config = dict()
응용 프로그램 전체에서 사용하는 방법은 정말 간단합니다. 가져오기 및 사용:
# file: app.py
from config import config
config['db'] = 'uat01'
config.update(host='localhost', username='user',
password='secret pass')
이러한
config
는 멋진 속성을 가지고 있습니다. 구현 트릭이 없는 싱글톤입니다.그러나
dict
로 요소에 액세스하는 []
구문을 사용하는 것이 특히 편리하지 않습니다. 빠른 수정은 다음 중 하나입니다.__*attr__
메서드에 대한 별칭을 만듭니다.# file: config.py
class Config(dict):
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
config = Config()
SimpleNamespace
에서 types
를 사용하지만 update()
동등한 방법이 없습니다. 상황이 바뀔 때
첫 번째 선택을 고수하고 다음 시나리오를 살펴보겠습니다.
# file: app.py
from config import config
from types import Optional
def fibonacci(
count: int,
first: Optional[int] = None,
second: Optional[int] = None
) -> int:
a, b = first or config.first, second or config.second
for _ in range(count):
a, b = b, a + b
return a
# file: main.py
from app import fibonacci
from config import config
if __name__ == '__main__':
config.update(first=1, second=1)
print(f'{fibonacci(6)=}')
config.update(first=3, second=5)
print(f'{fibonacci(6)=}')
결과는
fibonacci
함수에 대한 두 번의 호출 간에 변경되지 않습니다.fibonacci(6)=8
fibonacci(6)=8
변경 사항을 알리십시오.
# file: config.py
import importlib
import inspect
class Config:
_data = dict()
_referrers = set()
def __getattr__(self, name):
caller = inspect.currentframe().f_back
module_name = caller.f_globals['__name__']
if '__main__' not in module_name:
self._referrers.add(module_name)
try:
return self._data[name]
except KeyError:
raise AttributeError('no attr %s', name)
def __setattr__(self, name, value):
self._data[name] = value
def _reload_modules(self):
for module_name in self._referrers.copy():
module = importlib.import_module(module_name)
importlib.reload(module)
def __repr__(self):
return 'Config(%r)' % self._data
def update(self, reload=True, **kwargs):
for k, v in kwargs.items()
self.__setattr__(k, v)
if reload:
self._reload_modules()
config = Config()
# set defaults
config.update(first=0, second=1)
이제
main.py
를 실행하면 다음 결과가 생성됩니다.fibonacci(6)=8
fibonacci(6)=55
무슨 일이야?
좋습니다. 새로 정의된
Config
클래스는 약간 길고 약간의 설명이 필요합니다.코드를 살펴보겠습니다.
import importlib
import inspect
이 두 가지 가져오기는 잠시 후에 유용하게 사용할 수 있습니다.
class Config:
_data = dict()
_referrers = set()
Config
클래스는 두 가지 요소를 캡슐화합니다. 1. _data
, 실제 키-값 컨테이너 및 2. _referrers
, config
를 가져오고 해당 항목에 액세스하는 다른 모듈 집합입니다. def __getattr__(self, name):
caller = inspect.currentframe().f_back
module_name = caller.f_globals['__name__']
if '__main__' not in module_name:
self._referrers.add(module_name)
사용자 정의
__getattr__
는 도트 액세스 구문을 활성화합니다. 또한 config
를 참조하는 모듈을 녹음하는 순간입니다. config
가 업데이트되면 해당 모듈에 변경 사항이 있고 다시 로드할 시간임을 알릴 수 있습니다.나머지는 매우 간단합니다. 안에:
def _reload_modules(self):
for module_name in self._referrers.copy():
module = importlib.import_module(module_name)
importlib.reload(module)
관련 모듈을 반복하고 다시 로드합니다.
마지막으로 파일 끝에서 코드의 다른 부분에서 사용되는 항목의 기본값을 설정해야 합니다. 다른 옵션은 구성 파일을 로드하고 구문 분석하는 것입니다.
또한 설계상
update
에 대한 호출만 참조된 모듈을 새로 고치도록 결정했습니다. __setattr__
로 하나씩 설정하면 이 동작이 발생하지 않습니다.구성에 대한 귀하의 접근 방식은 무엇입니까?
Reference
이 문제에 관하여(Python 애플리케이션 변경 사항을 인식하는 구성 클래스), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/qoqosz/config-class-aware-of-your-python-application-changes-1dn6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)