我不太清楚Ruby是否足夠清楚地告訴你正在嘗試做什麼,但請查看__getattr__
方法。如果你在你的類中定義它,Python會在代碼試圖訪問你的類的其他未定義的屬性時調用它。既然你希望它成爲一個方法,它將需要創建一個即時返回的方法。
>>> class Product:
... def __init__(self, number):
... self.number = number
... def get_number(self):
... print "My number is %d" % self.number
... def __getattr__(self, attr_name):
... return lambda:"stubbed_"+attr_name
...
>>> p = Product(172)
>>> p.number
172
>>> p.name()
'stubbed_name'
>>> p.get_number()
My number is 172
>>> p.other_method()
'stubbed_other_method'
還要注意的是__getattr__
需要不使用你的類的其他任何未定義的屬性,否則將被無限遞歸調用__getattr__
爲不存在的屬性。
... def __getattr__(self, attr_name):
... return self.x
>>> p.y
Traceback (most recent call last):
#clipped
RuntimeError: maximum recursion depth exceeded while calling a Python object
如果這是你只想從你的測試代碼,而不是生產代碼做一些事情,然後把你的正常類定義生產代碼文件,然後在測試代碼中定義的__getattr__
方法(綁定) ,然後將其綁定到類,你想:
#production code
>>> class Product:
... def __init__(self, number):
... self.number = number
... def get_number(self):
... print "My number is %d" % self.number
...
#test code
>>> def __getattr__(self, attr):
... return lambda:"stubbed_"+attr_name
...
>>> p = Product(172)
>>> p.number
172
>>> p.name()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: Product instance has no attribute 'name'
>>> Product.__getattr__ = __getattr__
>>> p.name()
'stubbed_name'
我不知道如何做到這一點與已經使用__getattribute__
(相對於__getattr__
一類反應,__getattribute__
被稱爲所有屬性是否他們存在)。
如果你只是想爲已經存在的具體辦法做到這一點,那麼你可以這樣做:
#production code
>>> class Product:
... def __init__(self, number):
... self.number = number
... def get_number(self):
... return self.number
...
>>> p = Product(172)
>>> p.get_number()
172
#test code
>>> def get_number(self):
... return "stub_get_number"
...
>>> Product.get_number = get_number
>>> p.get_number()
'stub_get_number'
或者,如果你真的想成爲優雅,你可以創建一個包裝的功能,使幹多種方法很簡單:
#test code
>>> import functools
>>> def stubber(fn):
... return functools.wraps(fn)(lambda self:"stub_"+fn.__name__)
...
>>> Product.get_number = stubber(Product.get_number)
>>> p.get_number()
'stub_get_number'
我不完全以下是如何工作的。這是否滿足我的用例? – 2011-02-18 02:14:43
它應該;你的用例與你的例子幾乎相同。基本上,通過改變類的方法的定義,你也改變了它在所有實例上的定義。 'classmethod`函數創建一個基本上將函數轉換爲方法的包裝器,'lambda`定義函數來簡單地返回一個靜態字符串。 – kindall 2011-02-18 02:18:47
...但看到我的編輯。 – kindall 2011-02-18 02:34:20