Python使用变量等函数

时间:2015-06-19 01:20:17

标签: python

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

(?:\\<[^<>!]*?\\>\\n?)((.|\\n)*?)(?:\\<!.*\\>(\\n|$)?)

我想要做的只是更改# 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

# hardcoded_values.py import config foo = SomeWrapper(config.get_value, 'foo') # or whatever you can think of to call config.get_value('foo') ... 是使用变量config.get_value时使用参数'foo'调用的函数(如foo中所示)。

3 个答案:

答案 0 :(得分:2)

如果模块的客户端代码使用from hardcoded_variables import *,则无法执行此操作。这引用了另一个模块命名空间中hardcoded_variables的内容,之后你就无法对它们做任何事情。

如果可以将客户端代码更改为仅导入模块(例如import hardcoded_variables)然后访问其属性(使用hardcoded_variables.foo),则确实有机会,但这有点尴尬。< / p>

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()

答案 1 :(得分:2)

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

你想要做的是将foo设置为某个函数,然后应用property装饰器(或等效的),这样你就可以调用foo作为foo而不是{{ 1}}。您无法将属性装饰器应用于模块,原因如下:Why Is The property Decorator Only Defined For Classes?

现在,如果你去foo()那么我觉得有办法做你想要的import hardcoded_values。我有一种非常好的感觉,我将要描述的是一个永远不应该使用的 BAD IDEA ,但我认为它很有趣。

BAD IDEA ???

所以说你想用我的系统hardcoded_values.foo替换os.EX_USAGE之类的常量,然后将其称为64而不是os.EX_USAGE。我们需要能够使用os.EX_USAGE()装饰器,但为此我们需要property以外的类型。

所以可以做的是动态创建一个新类型并转储到模块的module中,该模块带有一个以模块为参数的类型工厂函数:

__dict__

现在我将导入os:

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

现在我将创建一个类>>> import os >>> os.EX_USAGE 64 >>> os.getcwd() '/Users/Eric' ,并将名称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

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

答案 2 :(得分:0)

如果我理解正确,您希望每次尝试访问变量时都会评估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]