使用类似variab的函数的Python

2024-05-29 02:57:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python模块,它有几个带有硬编码值的变量,它们在整个项目中使用。我想以某种方式将变量绑定到一个函数,以重定向到配置文件。这可能吗?在

# hardcoded_values.py
foo = 'abc'
bar = 1234

# usage somewhere else in another module
from hardcoded_values import *
print foo
print bar

我想做的是只改变hardcoded_values.py,这样print foo透明地调用一个函数。在

^{pr2}$

config.get_value是使用变量foo(如print foo)时用参数'foo'调用的函数。在


Tags: 模块项目函数py编码foo配置文件方式
3条回答

如果我理解正确,您希望每次尝试访问变量时都对hardcoded_variables模块求值。在

我可能在文档中有hardcoded_variables(例如json?)以及自定义包装函数,如:

import json
def getSettings(var):
    with open('path/to/variables.json') as infl:
        data = json.load(infl)
    return infl[var]

我很确定,如果像from hardcoded_values import *那样导入,您将无法执行您想要的操作。在

您要做的是将foo设置为某个函数,然后应用property修饰符(或等效函数),以便可以将foo作为foo而不是foo()来调用。不能将属性修饰符应用于模块,原因如下:Why Is The property Decorator Only Defined For Classes?

现在,如果你想import hardcoded_values,那么我想有一种方法可以做你想做的事情hardcoded_values.foo。我有一种很好的感觉,我将要描述的是一个永远不应该使用的坏主意,但我认为它很有趣。在


坏主意???

假设您想用某个函数替换一个常量,比如os.EX_USAGE,在我的系统中是64,然后将其称为os.EX_USAGE,而不是{}。我们需要能够使用property修饰符,但为此我们需要一个module以外的类型。在

因此,可以做的是动态创建一个新类型,并在模块的__dict__中转储一个类型工厂函数,该函数以模块为参数:

def module_class_factory(module):
    ModuleClass = type('ModuleClass' + module.__name__, 
                       (object,), module.__dict__)
    return ModuleClass

现在我将导入操作系统:

^{pr2}$

现在我将创建一个类OsClass,并将名称os绑定到该类的一个实例:

>>> OsClass = module_class_factory(os)
>>> os = OsClass()
>>> os.EX_USAGE
64
>>> os.getcwd()
'/Users/Eric'

一切似乎仍然有效。现在定义一个函数来替换os.EX_USAGE,注意它需要一个伪的self参数:

>>> def foo(self):
...     return 42
... 

…并将类属性OsClass.EX_USAGE绑定到函数:

>>> OsClass.EX_USAGE = foo
>>> os.EX_USAGE()
42

os对象调用它时,它会工作!现在只需应用属性装饰器:

>>> OsClass.EX_USAGE = property(OsClass.EX_USAGE)
>>> os.EX_USAGE
42

现在,模块中定义的常量已经被函数调用透明地替换了。在

如果模块的客户机代码使用from hardcoded_variables import *,则绝对不能这样做。这将引用另一个模块的名称空间中的hardcoded_variables的内容,之后您将无法对它们执行任何操作。在

如果客户机代码可以更改为只导入模块(例如import hardcoded_variables),然后访问它的属性(使用hardcoded_variables.foo),那么您确实有机会,但是有点尴尬。在

Python缓存导入到sys.modules(字典)中的模块。可以用其他对象(如自定义类的实例)替换该字典中的模块,并在访问对象属性时使用property对象或其他描述符来实现特殊行为。在

试着让新的hardcoded_variables.py看起来像这样(并且考虑重命名它!)公司名称:

import sys

class DummyModule(object):
    def __init__(self):
        self._bar = 1233

    @property
    def foo(self):
        print("foo called!")
        return "abc"

    @property
    def bar(self):
        self._bar += 1
        return self._bar

if __name__ != "__main__":    # Note, this is the opposite of the usual boilerplate
    sys.modules[__name__] = DummyModule()

相关问题 更多 >

    热门问题