Python类继承MonkeyDevice

时间:2013-05-02 19:26:48

标签: android python monkeyrunner

我按照这里给出的解决方案,添加了一个方法来将功能扩展到我的Device类。 How to inherit from MonkeyDevice?

我得到一个错误对象没有属性'test'。看起来我的Class实例是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)

2 个答案:

答案 0 :(得分: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 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"

答案 1 :(得分:1)

__new__是用于实际实例化对象的方法。因为你已经重写它并显式返回了MonkeyRunner.waitForConnection返回的内容,所以device实际上并不是类Device的实例。

很少需要覆盖__new__

编辑 好的,我从链接的答案中看到,这是你需要这样做的情况。 Bakuriu的答案显示了一些使用特殊构造函数来实例化对象的方法,__new__的文档也是如此:Python docs

作为一个小注,按照惯例,__new__的第一个参数是cls而不是self,因为它实际上是类对象本身而不是实例。