在 Python 中如何只初始化一次变量,然后将其导入其余模块?
我有以下python项目结构:
- 应用程序接口
- v1
- init.py
- v2
- init.py
- init.py
- v1
- logging.py
logging.py:
from raven import Client
sentry = None
def init_sentry():
global sentry
sentry = 'some_dsn'
API/初始化.py
from app import logging
logging.init_sentry()
#run flask server (v1,v2)
API/{v1,v2}/init.py
from logging import sentry
try:
1 / 0
except ZeroDivisionError:
sentry.captureException()
在文件 api/v1/init.py 和 api/v2/init 中.py在哨兵变量上获取错误 NoneType。我知道当我使用它时,我可以在所有文件中调用init_sentry,但我正在寻找更好的方法。
谢谢
首先,我认为你拼错了init.py
,应该是__init__.py
。
在带有变量的模块之间传递数据是一种糟糕的编程风格。应使用类或函数来处理共享数据。以这种方式,您有一个API,并且很清楚其他模块可以修改哪些变量。
但是对于您的问题:我(真的不会(创建一个带有shared = {}
字典的模块data.py
。从其他模块,只需导入我就可以共享数据。 通过查看变量或只是一个标志moduleA_initialized
,您可以决定是否需要初始化模块。
作为替代方案,您可以直接写入字典globals()
。注意:这是更糟糕的编程实践,您应该仔细检查名称,以便与您可能使用的任何库都没有冲突。 gettext
写信给它,但这是非常特殊的情况。
这是一种封装 sentry
变量并确保它始终调用某些东西的方法,而不是访问None
:
logging.py:
class Sentry(object):
_dsn = None
@classmethod
def _set_dsn(cls, dsn):
cls._dsn = dsn
@classmethod
def __getattr__(cls, item):
return getattr(cls._dsn)
sentry = Sentry
def init_sentry():
Sentry._set_dsn('some_dsn')
注意:
这个答案也是正确的,你可能想要__init__.py
而不是init.py
.