Pass Variable On Import

后端 未结 8 1412
轻奢々
轻奢々 2020-12-16 09:37

Let\'s say you have some time-consuming work to do when a module/class is first imported. This functionality is dependent on a passed in variable. It only needs to be done

8条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-16 10:02

    If there is only one configuration item to set, then I have found overriding the python __builtin__ to work just fine, but it is an example of "Monkey patching" which is frowned on by some.

    A cleaner way to do it which is very useful for multiple configuration items in your project is to create a separate Configuration module that is imported by your wrapping code first, and the items set at runtime, before your functional module imports it. This pattern is often used in other projects.

    myconfig/__init__.py :

    PATH_TO_R_SOURCE   = '/default/R/source/path'
    OTHER_CONFIG_ITEM  = 'DEFAULT'
    PI                 = 3.14
    

    mymodule/__init__.py :

    import myconfig
    
    PATH_TO_R_SOURCE = myconfig.PATH_TO_R_SOURCE
    robjects.r.source(PATH_TO_R_SOURCE, chdir = True) ## this takes time
    
    class SomeClass:
      def __init__(self, aCurve):
        self._curve = aCurve
    
    if myconfig.VERSION is not None:
      version = myconfig.VERSION
    else:
      version = "UNDEFINED"
    
    two_pi = myconfig.PI * 2
    

    And you can change the behaviour of your module at runtime from the wrapper:

    run.py :

    import myconfig
    
    myconfig.PATH_TO_R_SOURCE = 'actual/path/to/R/source'
    myconfig.PI = 3.14159
    # we can even add a new configuration item that isn't present in the original myconfig:
    myconfig.VERSION="1.0"
    
    import mymodule
    print "Mymodule.two_pi = %r" % mymodule.two_pi
    print "Mymodule.version is %s" % mymodule.version
    

    Output:

    > Mymodule.two_pi = 6.28318
    > Mymodule.version is 1.0
    

提交回复
热议问题