簡體   English   中英

用 Python 編寫一個無操作或虛擬類

[英]Write a no-op or dummy class in Python

假設我有這樣的代碼:

foo = fooFactory.create()

由於各種原因, fooFactory.create()可能無法創建Foo的實例。

如果是這樣,我希望fooFactory.create()返回一個虛擬/無操作對象。 這個對象應該是完全惰性的——無論它如何使用,它都不應該做任何事情或拋出任何異常。 請注意, foo沒有返回值的方法。


我考慮了以下選項。

首先,創建一個模擬 這樣做的好處是它很容易,並且可以給我我想要的東西。 缺點是在生產代碼中使用模擬感覺很奇怪。 更重要的是,我無法控制模擬庫,因此它的行為可能會在某些時候發生變化並破壞我的應用程序。

其次,創建一個虛擬的NoopFoo / DummyFoo類。 然后我手動實現它需要支持的方法,並將pass放在方法體中。 我知道它永遠不會破壞我的應用程序的好處。 缺點是,如果將來使用Foo其他方法,我必須知道更新NoopFoo / DummyFoo ... 否則我的應用程序可能會中斷。

還有比這兩個更好的選擇嗎? 請注意,我是 Python 的新手,因此如果它涉及更高級的 Python 功能,我將不勝感激。 謝謝!

你要求一個什么都不做的對象。 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)

這個怎么樣:

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

一個 Dummy 對象對任何屬性訪問都不做任何響應。

先前使用虛擬對象的答案不適用於嵌套的屬性/方法。 這是我的解決方案:

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>

考慮通過pip install nop獲得的nop包。 請不要使用mock包(測試除外),因為它存儲調用歷史!

from nop import NOP

dummy = NOP()

dummy.foo()
NOP
dummy.foo().bar()
NOP
dummy.foo('x', 'y')
NOP
dummy.foo('x', 'y', z=3)
NOP

type(_)
<class 'nop.nop_base.NOP'>

它的源代碼在這里

class Dummy(object):
    pass

a = Dummy()

# want to add a method?
a.something = lambda self: "hi"

print a.something()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM