0

我遵循此处给出的解决方案,并添加了一种将功能扩展到我的设备类的方法。 如何从 MonkeyDevice 继承?

我得到一个错误对象没有属性“测试”。看起来我的 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)
4

2 回答 2

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实例。您在问题中链接的答案指出:

无论如何,要实现您想要的,您应该使用 custom __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"
于 2013-05-02T19:51:33.300 回答
1

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

很少需要覆盖__new__.

编辑 好的,我从链接的答案中看到这是您需要这样做的情况。Bakuriu 的答案显示了一些使用特殊构造函数来实例化对象的方法,就像以下文档一样__new__Python docs

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

于 2013-05-02T19:55:46.390 回答