不确定这是否可以在Python中使用,但我希望将类的实例作为模块级全局变量,在调用时,返回默认属性。
这个想法来自this question,它会覆盖__call__
以使某个类模仿一个函数。
这个想法的快速(未经测试)示例:
class _foo(object):
__slots__ = ("_foo",)
_init = False
def __init__(self):
if not _init:
self._foo = ["bar", "baz", "zog"]
def __call__(self, item=None):
if itme is not None:
return self._foo[item]
else:
return self._foo
def __getitem__(self, item):
return self._foo[item]
# Module level
FOO = _foo()
假设上面的代码在一个模块(foo.py)中。使用解释器,我得到可调用的表单来工作我想要的,但不是不可调用的表单。
>>> import foo
# callable forms
>>> foo.FOO(0)
"bar"
>>> foo.FOO()
["bar", "baz", "zog"]
# attribute forms
>>> foo.FOO[2]
"zog"
# doesn't work
>>> foo.FOO
<foo._foo object at 0xdeadbeef>
# desired output
>>> foo.FOO
["bar", "baz", "zog"]
我的想法是我需要以某种方式定义默认属性,以便在直接调用实例时,我得到我选择的内部列表/字典。我可以通过重写 repr 来欺骗并做到这一点,但这有点打破了Python自己的API,我想避免这种情况。在方括号(>>> foo.FOO[]
)中不传递值会产生语法错误。
我希望任何可能的解决方案至少与Python 2.4兼容,最多兼容2.7。如果这是不可能的,那么我想我只会坚持使用可调用的格式。
答案 0 :(得分:2)
这是不可能的,对不起。您不能让foo.FOO
同时成为可调用的(_foo
实例)和未掺杂的列表对象。
当然,我确实说过“纯粹的”。如果你感觉偷偷摸摸......
class _foo(list):
_init = False
def __init__(self):
if self._init:
list.__init__(self)
else:
list.__init__(self, ['bar', 'baz', 'zog'])
def __call__(self, item=None):
if item is None:
return self
return self[item]
FOO = _foo()
用法:
>>> FOO()
['bar', 'baz', 'zog']
>>> FOO(0)
'bar'
>>> FOO
['bar', 'baz', 'zog']
答案 1 :(得分:1)
我不确定你的意思现在,当我在另一个模块中尝试这个时,我得到一个AttirbuteError模块中不存在FOO ,这个代码导入你的模块对我来说正常工作
import foo
FOO2 = foo.FOO
print(FOO2())
print(FOO2(1))
Python 2.7.3
答案 2 :(得分:0)
在类上定义__repr__(self)
以定义其实例在Python inteprreter中的显示方式。在这种情况下,也许return repr(self._foo)
。