简体   繁体   English

Python类继承MonkeyDevice

[英]Python class to inherit MonkeyDevice

I followed the solution as given here and added a method to extend functionality to my Device class. 我按照这里给出的解决方案,添加了一个方法来将功能扩展到我的Device类。 How to inherit from MonkeyDevice? 如何从MonkeyDevice继承?

I get an error object has no attribute 'test'. 我得到一个错误对象没有属性'test'。 Looks like my Class instance is of type MonkeyDevice. 看起来我的Class实例是MonkeyDevice类型。 What am I doing wrong? 我究竟做错了什么?

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)

You are doing a lot of things wrong. 你做了很多错事。 Unfortunately I don't use monkeyrunner so I can't help you with the details related to the library itself. 不幸的是我没有使用monkeyrunner所以我无法帮助您了解与库本身相关的细节。

What your code does is something like the following: 您的代码的作用如下:

>>> 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

Note how device is not a Device instance. 请注意device 不是 Device实例。 The reason is the your __new__ method is not returning a Device instance, but a MonkeyRunner instance. 原因是你的__new__方法没有返回一个Device实例,而是一个MonkeyRunner实例。 The answer that you linked in your question states: 您在问题中链接的答案说明:

Anyway to achieve what you want you should create a class with custom __new__ rather than __init__ , get your MonkeyDevice instance from the factory and inject your stuff into the instance or it's class/bases/etc. 无论如何要实现你想要的你应该创建一个自定义__new__而不是__init__ ,从工厂获取你的MonkeyDevice实例并将你的东西注入实例或它的class / bases / MonkeyDevice

Which means you should have done something like: 这意味着你应该做的事情如下:

>>> 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

However this isn't useful at all, since the Device could simply be a function: 但是这根本没用,因为Device可能只是一个函数:

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

AFAIK you cannot subclass MonkeyRunner and create the instance from its waitForConnection method, at least if waitForConnection is a staticmethod . AFAIK你不能将MonkeyRunner子类MonkeyRunner并从其waitForConnection方法创建实例,至少如果waitForConnectionstaticmethod

What I'd do is to use delegation: 我要做的是使用委托:

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"

__new__ is the method used to actually instantiate the object. __new__是用于实际实例化对象的方法。 Because you've overridden it and explicitly returned whatever MonkeyRunner.waitForConnection returns, device is not actually an instance of class Device. 因为你已经重写它并显式返回了MonkeyRunner.waitForConnection返回的内容,所以device实际上并不是类Device的实例。

It's rare to need to override __new__ . 很少需要覆盖__new__

edited OK, I see from the linked answer that this is a case where you need to do that. 编辑好了,我从链接的答案中看到,这是你需要这样做的情况。 Bakuriu's answers show some ways to work with the need to use the special constructor to instantiate the object, as do the docs for __new__ : Python docs Bakuriu的答案显示了一些使用特殊构造函数来实例化对象的方法, __new__的文档也是__new__Python文档

As a minor note, by convention the first argument to __new__ is cls rather than self, because it's actually the class object itself rather than an instance. 作为次要注释,按照惯例, __new__的第一个参数是cls而不是self,因为它实际上是类对象本身而不是实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM