简体   繁体   中英

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:

app_config.py :

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

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 :

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 :

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. 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. 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.

  2. Similarly, I want to use app_library.py by multiple scripts in the same directory. 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 .

  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. How can (or should?) app_library.py functions access this instance of the logger class?

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. In a simple version, that gives you one global variable which all your code shares. app_name = "quick scraper" becomes:

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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