2013-05-02 106 views
0

我也跟着解決方案,這裏給出並添加到功能擴展到設備類中的方法。 How to inherit from MonkeyDevice?Python類繼承MonkeyDevice

我得到一個錯誤的對象有沒有屬性「測試」。看起來像我的類實例是MonkeyDevice類型。我究竟做錯了什麼?

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage 

class Device(MonkeyDevice): 

    def __new__(self): 
     return MonkeyRunner.waitForConnection(10) 
    def __init__(self): 
     MonkeyDevice.__init__(self) 
    def test(): 
     print "this is test" 

device = Device() 
device.test(self) 

回答

1

你正在做的很多事情是錯誤的。不幸的是,我不使用monkeyrunner,所以我無法幫助您瞭解與庫本身相關的細節。

你的代碼做什麼是類似如下:

>>> class MonkeyRunner(object): pass 
... 
>>> class Device(MonkeyRunner): 
...  def __new__(self): 
...    return MonkeyRunner() 
...  def __init__(self): 
...    super(Device, self).__init__() 
...  def test(): 
...    print "This is test" 
... 
>>> device = Device() 
>>> device.test(self) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'MonkeyRunner' object has no attribute 'test' 
>>> device 
<__main__.MonkeyRunner object at 0xb743fb0c> 
>>> isinstance(device, Device) 
False 

注意如何device一個Device實例。原因是您的__new__方法未返回Device實例,而是一個MonkeyRunner實例。你在你的問題鏈接的答案說:

反正達到你想要,你應該創建一個自定義的類 __new__而非__init__,從工廠讓您MonkeyDevice實例 和注入你的東西到什麼實例或它的 class/bases /等。

這意味着你應該做的是這樣的:

>>> class Device(MonkeyRunner): 
...  def __new__(self): 
...    inst = MonkeyRunner() 
...    inst.test = Device.test 
...    return inst 
...  @staticmethod 
...  def test(): 
...    print "I'm test" 
... 
>>> device = Device() 
>>> device.test() 
I'm test 

然而,這是沒有作用的,因爲Device可能僅僅是一個功能:

>>> def Device(): 
...  def test(): 
...    print "I'm test" 
...  inst = MonkeyRunner() 
...  inst.test = test 
...  return inst 
... 
>>> device = Device() 
>>> device.test() 
I'm test 

AFAIK你不能子類MonkeyRunner並從其waitForConnection方法創建實例,至少如果waitForConnectionstaticmethod

我會做的是使用委託:

class Device(object): 
    def __init__(self): 
     self._device = MonkeyRunner.waitForConnection(10) 
    def __getattr__(self, attr): 
     return getattr(self._device, attr) 
    def test(self): 
     print "I'm test" 
+0

非常感謝你的回答,尤其是最後一個答案。 – user2344495 2013-05-02 21:33:46

1

__new__是用於實際實例化對象的方法。由於您重寫了它並明確返回了MonkeyRunner.waitForConnection返回的任何內容,因此設備實際上不是類Device的實例。

也很少需要重寫__new__

編輯 好的,我從鏈接的答案中看到,這是一種您需要這樣做的情況。 Bakuriu的回答表現出一定的方式與需要使用特殊的構造函數來實例化對象的工作,因爲這樣做對__new__文檔:Python docs

作爲未成年人注意到,按照慣例,第一個參數__new__是CLS,而不是自我,因爲它實際上是類對象本身而不是實例。