2013-05-02 108 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,而不是自我,因为它实际上是类对象本身而不是实例。