2013-03-15 76 views
1

在python中,我想創建一個帶有多個點的(類)方法,以便進行關於xmlrpc方法的測試,該方法可以包含多個點的方法名稱。當我嘗試以下操作:如何創建一個多點的類方法?

class Foo(object): 
    def method.with.many.dots(self): 
     return 42 

我有一個無效的語法。我也嘗試使用更復雜的想法,如

class Foo(object): 
    def __getattr__(self, attr): 
     print attr 

這也不能用方法名稱帶點的方法。任何想法如何,我可以創建一個簡單的模擬對象與我可以做Python代碼類似

mock.some.test.with.many.dots() 

以簡單的方式,而無需啓動xmlrpc服務器?

+2

Python將其評估爲mock對象'some'屬性的'test'屬性的'many'屬性的'dots'方法。 – whatyouhide 2013-03-15 10:37:31

+0

[HYRY的解決方案](http://stackoverflow.com/a/15430170/1974792)是您需要的一個,但它不適用於'with'或任何其他關鍵字,如在您的示例中。 – dmg 2013-03-15 10:39:09

回答

8
class Foo(object): 
    def __init__(self): 
     self._attr_path = [] 

    def __getattr__(self, attr): 
     self._attr_path.append(attr) 
     return self 

    def __call__(self, *args, **kw): 
     print ".".join(self._attr_path) 
     print args, kw 
     del self._attr_path[:] 

f = Foo() 
f.a.b.c(1,2,3) 

此輸出:

a.b.c 
(1, 2, 3) {} 

要解決@Daira霍普伍德的問題:

class Bar(object): 
    def __init__(self, foo, attr): 
     self.foo = foo 
     self._attr_path = [attr] 

    def __getattr__(self, attr): 
     self._attr_path.append(attr) 
     return self 

    def __call__(self, *args, **kw): 
     print self 
     print args, kw 

    def __str__(self): 
     return ".".join(self._attr_path) 

class Foo(object): 

    def __getattr__(self, attr): 
     return Bar(self, attr) 

f = Foo() 
f.a.b.c(1,2,3) 

要重新修復@Daira霍普伍德的問題:

class Foo(object): 

    def __init__(self, parent=None, name=""): 
     self.parent = parent 
     self.name = name 

    def __getattr__(self, attr): 
     return Foo(parent=self, name=attr) 

    def __call__(self, *args, **kw): 
     print self 
     print args, kw  

    def __str__(self): 
     nodes = [] 
     node = self 
     while node.parent: 
      nodes.append(node) 
      node = node.parent 
     return ".".join(node.name for node in nodes[::-1]) 

f = Foo() 
x = f.a.b 
y = f.a.c 
x() 
y() 

g = f.a 
f.b 
g.b.c() 
+0

你以秒爲單位打敗了我,好的先生。 – dmg 2013-03-15 10:37:49

+0

精彩的解決方案,非常感謝你! – Alex 2013-03-15 12:18:14

+0

如果一個屬性鏈在沒有中間調用的情況下被訪問多次,該解決方案將失敗。如果您希望它能夠穩健地工作,那麼您確實需要表示鏈的元素的多個對象。 – 2013-11-20 21:49:29

1

該解決方案將工作

輸入:

import mock 
MO = mock.Mock() 
MO.some.test.wyth.many.dots.return_value = 42 
MO.some.test.wyth.many.dots() 

輸出:

42 

注意, 「用」 是一個關鍵詞。

每個虛線的「後代」是一個獨立的(模擬)對象。

相關問題