Python 中共享全局变量、共享函数和类的最佳/您的实践

Dev*_*wen 0 python python-2.7

本质上,我想让我的代码更加模块化和可共享:您可以看到以下文件最初是如何组成一个更大的文件的。它不起作用,我怀疑这是因为我试图用 Python 做一些我不应该做的事情:

app_config.py

app_name = "quick scraper"
mysql_db = ...    # intended "global" variable that connects to database
Run Code Online (Sandbox Code Playgroud)

main.py

from app_config import *                  # Getting shared variables
import app_library                        # See code app_library.py below 
...
logger = logging.getLogger(app_name)      # logger object to be shared later
...
app_library.dlAndSaveWebpage(url)         # Module has key helper functions
...
Run Code Online (Sandbox Code Playgroud)

app_library.py

import app_models_orm as app_models

def dlAndSaveWebpage(url)
  # download and process url
  ...
  app_models.Webpage.create(url=url, body=body)
Run Code Online (Sandbox Code Playgroud)

app_models_orm.py

class MySQLModel(Model):
  class Meta:
    database = mysql_db

class Webpage(MySQLModel):
  id = ...
  ...
Run Code Online (Sandbox Code Playgroud)
  1. 类失败MySQLModelapp_models_orm.py因为mysql_db文件中不存在变量。我可以做一个import app_config,但我希望被app_models_orm.py同一目录中的多个脚本使用。如果我必须将自定义文件导入到脚本中,那么我必须复制模型文件,这看起来很奇怪且错误。

  2. 同样,我想app_library.py在同一目录中由多个脚本使用。app_library从调用似乎是有意义的main.py,但如果app_library需要直接从 引用变量app_config.py,我还必须复制app_library.py.

  3. main.py包含一个logger对象,当所有这些代码都放在一个文件中时,所有各种方法都可以访问/使用该对象。函数如何(或应该?)app_library.py访问记录器类的此实例?

在这种情况下,也可以随意“教我如何钓鱼”:我看到很多关于使用全局导入文件的帖子,但这无助于在不添加自定义导入的情况下共享后两个文件的意图,也无济于事帮助模型文件导入时,会出现错误,因为该类正在寻找文件中不存在的变量。可能有一个正确的方法来完成这一切。

Aar*_*lla 5

为了使代码更加模块化,第一步始终是将所有全局变量移动到“config”对象中。在一个简单的版本中,它为您提供了一个所有代码共享的全局变量。app_name = "quick scraper"变成:

class Config(object):
    def __init__(self):
        self.app_name = "quick scraper"

config = Config()
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

logger = logging.getLogger(config.app_name)
Run Code Online (Sandbox Code Playgroud)

在下一步中,您将更改代码以使用类,这些类获取对当前配置的引用作为参数__init__。这允许您拥有多个配置并摆脱所有全局变量:

class Main(object):
    def __init__(self, config):
        self.config = config

        self.logger = logging.getLogger(self.config.app_name)

        ...

        self.app_library = AppHelper(self.config)
        self.app_library.dlAndSaveWebpage(url)
Run Code Online (Sandbox Code Playgroud)

这意味着您需要将所有(或大部分)函数转换为辅助类的方法。