简体   繁体   English

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

[英]Best/your practices in Python for sharing global variables, shared functions and classes

Thanks for looking at this, I've been mulling over this for hours to no avail. 感谢您查看此内容,我已经考虑了好几个小时而徒劳无功。 Essentially, I want to make my code more modular and share-able: you can see how the following files made up a much larger one initially. 本质上,我想使代码更具模块化和可共享性:您可以看到以下文件最初是如何构成更大的文件的。 It's not working and I suspect it's because I'm trying to do things in Python that I'm not supposed to: 它不起作用,我怀疑是因为我试图用Python做我不应该做的事情:

app_config.py : app_config.py

app_name = "quick scraper"
mysql_db = ...    # intended "global" variable that connects to database

main.py : 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
...

app_library.py : 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)

app_models_orm.py : app_models_orm.py

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

class Webpage(MySQLModel):
  id = ...
  ...
  1. Class MySQLModel of app_models_orm.py fails because variable mysql_db does not exist in the file. MySQLModelapp_models_orm.py因变量无法mysql_db没有在文件中存在。 I could do an import app_config , but I want to have app_models_orm.py be used by multiple scripts within the same directory. 我可以执行import app_config ,但是我想让app_models_orm.py由同一目录中的多个脚本使用。 If I have to do an import of a file custom to a script, then I'd have to make copies of the models file, which just seems bizarre and wrong. 如果必须将文件自定义导入脚本,那么我就必须复制models文件,这看起来很奇怪而且是错误的。

  2. Similarly, I want to use app_library.py by multiple scripts in the same directory. 同样,我想在同一目录中的多个脚本中使用app_library.py It seems to make sense to call app_library from main.py , but if app_library needs to reference variables directly from app_config.py , I'd have to also make copies of app_library.py . main.py调用app_library似乎main.py ,但是如果app_library需要直接从app_config.py引用变量,那么我还必须复制app_library.py

  3. main.py contains a logger object that, when all of this code was put together in one file, all the various methods could access/use. main.py包含一个logger对象,当将所有这些代码放到一个文件中时,所有各种方法都可以访问/使用。 How can (or should?) app_library.py functions access this instance of the logger class? app_library.py函数如何(或应该?)访问logger类的此实例?

Again, thanks for the help. 再一次感谢你的帮助。 Feel free to "teach me how to catch fish" in this instance too: I saw many posts about using a global import file, but that doesn't help the intention to share the latter two files without adding in custom imports, nor does it help with the models file which, when imported, hits an error because the class is seeking a variable that isn't in the file. 在这种情况下,也请随时“教我如何钓鱼”:我看到了很多有关使用全局导入文件的文章,但这无助于在不添加自定义导入的情况下共享后两个文件的意图,也没有帮助。帮助模型文件,该文件在导入时出现错误,因为类正在寻找文件中未包含的变量。 There's probably a right way to do all this, and I imagine many of you would know how. 解决所有这些问题可能是正确的方法,我想你们中的许多人会知道如何做。

To make code more modular, the first step is always to move all global variables into a "config" object. 为了使代码更具模块化,第一步始终是将所有全局变量移到“ config”对象中。 In a simple version, that gives you one global variable which all your code shares. 在一个简单的版本中,这为您提供了一个全局变量,所有代码都共享该变量。 app_name = "quick scraper" becomes: app_name = "quick scraper"变为:

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

config = Config()

You can then use this like so: 然后可以这样使用:

logger = logging.getLogger(config.app_name)

In the next step, you change the code to use classes which get a reference to the current config as an __init__ parameter. 在下一步中,您将代码更改为使用类,这些类获得对当前配置的引用作为__init__参数。 That allows you to have several configs and get rid of all the globals: 这使您可以进行多个配置并摆脱所有全局变量:

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)

That means you need to turn all (or most of) your functions into methods of helper classes. 这意味着您需要将所有(或大部分)函数转换为帮助程序类的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM