在Python中写一个无操作或伪类
假设我有这样的代码:
foo = fooFactory.create()
出于各种原因,fooFactory.create()
可能无法创建一个 Foo
的实例。
如果创建失败,我希望 fooFactory.create()
返回一个虚假的/无操作的对象。这个对象应该完全无效——无论怎么使用,它都不应该做任何事情,也不会抛出任何异常。需要注意的是,foo
没有返回值的方法。
我考虑了以下几种选择。
首先,创建一个模拟对象。这样做的好处是简单明了,正好能满足我的需求。坏处是,在生产代码中使用模拟对象感觉有点奇怪。更重要的是,我无法控制这个模拟库,所以它的行为可能会在某个时候发生变化,从而导致我的应用程序出错。
第二,创建一个虚拟对象 NoopFoo
/ DummyFoo
类。我会手动实现它需要支持的方法,并在方法体内简单地写上 pass
。这样做的好处是我知道它不会导致我的应用程序出错。坏处是,如果将来使用了 Foo
的其他方法,我就得知道去更新 NoopFoo
/ DummyFoo
,否则我的应用程序可能会出错。
有没有比这两种选择更好的方法呢?请注意,我是 Python 新手,如果涉及到更高级的 Python 特性,希望能多给点信息。谢谢!
4 个回答
5
之前的回答提到的那些虚拟对象在处理嵌套属性或方法时并不好用。这里是我的解决方案:
class Dummy:
def __init__(*args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return self
def __getattr__(self, *args, **kwargs):
return self
现在我们可以访问嵌套的属性和方法了:
>>> d = Dummy()
>>> d.my_attr
<__main__.Dummy object at 0x10d007160>
>>> d.my_method()
<__main__.Dummy object at 0x10d007160>
>>> d.my_attr.my_method()
<__main__.Dummy object at 0x10d007160>
>>> d.my_attr.my_other_attr
<__main__.Dummy object at 0x10d007160>
10
这个怎么样:
class MayBeCalled(object):
def __call__(self, *args, **kwargs):
return None
class Dummy(object):
def __getattr__(self, attr):
return MayBeCalled()
def __setattr__(self, attr, val):
pass
a = Dummy()
print a.nn
<__main__.MayBeCalled object at 0x103ca9a90>
print a.nn()
None
a.nn = 23
print a.nn()
None
一个“虚拟”对象在你访问它的任何属性时,什么都不做。
15
你问的是一个什么都不做的对象。object
的实例正好就是这样。
def create():
return object()
另一方面,你可能希望它能做点什么。你可能希望它有一些方法,这些方法执行后返回None
。你可以返回这个类的一个实例:
In [1]: class Nop(object):
...: def nop(*args, **kw): pass
...: def __getattr__(self, _): return self.nop
...:
In [2]: n=Nop()
In [3]: n.foo
Out[3]: <bound method Nop.nop of <__main__.Nop object at 0x7f9fec034650>>
In [4]: n.foo()
In [5]: n.foo(1,2,3)