假设我有这样的代码:
foo = fooFactory.create()
Run Code Online (Sandbox Code Playgroud)
由于各种原因,fooFactory.create()可能无法创建实例Foo.
如果是,我想fooFactory.create()返回一个虚拟/无操作对象.这个对象应该是完全惰性的 - 无论它如何使用,它都不应该做任何事情或抛出任何异常.请注意,foo没有返回值的方法.
我考虑过以下几种选择.
首先,创建一个模拟.这样做的好处是它很容易并且完全符合我的要求.缺点是在生产代码中使用模拟会感觉很奇怪.更重要的是,我无法控制模拟库,因此它的行为可能会在某些时候发生变化并破坏我的应用程序.
其次,创建一个虚拟 NoopFoo/DummyFoo类.然后我手动实现它需要支持的方法,然后放入pass方法体.我知道它的优点永远不会破坏我的应用程序.缺点是,如果Foo将来使用其他方法,我必须知道更新NoopFoo/ DummyFoo...或我的应用程序可能会中断.
有没有比这两种更好的选择?请注意,我是Python的新手,所以如果它涉及更高级的Python功能,我会感激更多的信息.谢谢!
这个怎么样:
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
Run Code Online (Sandbox Code Playgroud)
虚拟对象响应任何无效的属性访问.
你要求一个什么都不做的物体.一个例子object正是这样做的.
def create():
return object()
Run Code Online (Sandbox Code Playgroud)
另一方面,您可能实际上希望它能够做某事.您可能希望它具有执行和返回的方法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)
Run Code Online (Sandbox Code Playgroud)
前面关于虚拟对象的答案不适用于嵌套属性/方法。这是我的解决方案:
class Dummy:
def __init__(*args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return self
def __getattr__(self, *args, **kwargs):
return self
Run Code Online (Sandbox Code Playgroud)
现在我们可以访问嵌套的属性和方法:
>>> 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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3683 次 |
| 最近记录: |