0

我不太确定如何最好地解释我想要的,所以我只显示一些代码:

class Stuffclass():
    def add(self, x, y):
        return x + y

    def subtract(self, x, y):
        return x - y

    # imagine that there are 20-30 other methods in here (lol)

class MyClass:
    def __init__(self):
        self.st = Stuffclass()

    def doSomething(self):
        return self.st.add(1, 2)

m = MyClass()
m.doSomething() # will print 3
# Now, what I want to be able to do is:
print m.add(2, 3) # directly access the "add" method of MyClass.st
print m.subtract(10, 5) # directly access the "subtract" method of MyClass.st
m.SomeMethod() # execute function MyClass.st.SomeMethod

我知道我可以做这样的事情:

class MyClass:
    def __init__(self):
        self.st = Stuffclass()
        self.add = self.st.add
        self.subtract = self.st.subtract

...但这需要手动分配所有可能的属性。

我正在编写所有类,所以我可以保证没有名称冲突。

使 MyClass 成为 Stuffclass 的子类是行不通的,因为我实际上是在基于插件的应用程序中使用它,其中 MyClass 使用import动态加载其他代码。这意味着 MyClass 不能从插件继承,因为插件可以是遵循我的 API 的任何东西。

请指教?

4

2 回答 2

1

用于__getattr__将调用委托给Stuffclass的实例:

class MyClass:
    def __init__(self):
        self.st = Stuffclass()

    def __getattr__(self,attr):
        return getattr(self.st,attr)

演示:

>>> from so import *
>>> m = MyClass()
>>> m.add(1,2)
3
>>> m.subtract(100,2)
98
于 2013-07-07T21:33:38.730 回答
1

我相信为你的班级写一个getattr函数会让你做你想做的事。

当属性查找在通常的位置没有找到属性时调用(即它不是实例属性,也不是在 self 的类树中找到)。name 是属性名称。此方法应返回(计算的)属性值或引发 AttributeError 异常

所以一些简单的事情:

def __getattr__(self, name):
    if hasattr(self.st, name):
        return getattr(self.st, name)
    else:
        raise AttributeError

应该大致做你所追求的。

但是,在回答了(我认为)您提出的问题后,我将继续讨论我认为您应该提出的问题。

我实际上在基于插件的应用程序中使用它,其中 MyClass 使用 import 动态加载其他代码。这意味着 MyClass 不能从插件继承,因为插件可以是遵循我的 API 的任何东西

我明白为什么 MyClass 不能是 StuffClass 的子类;但是 StuffClass 不能是 MyClass 的子类吗?如果您以这种方式定义继承,则可以保证 StuffClass 实现了 MyClass 中的所有基本内容,并且的 StuffClass 实例具有在 StuffClass 中定义的所有额外方法。

从您提到插件需要“遵循我的 API”开始,我假设您可能需要确保插件实现一组方法以符合 API;但由于方法的实现将取决于插件的细节,因此您无法在 MyClass 中提供这些功能。在这种情况下,听起来好像定义一个插件需要继承的抽象基类可能对您有用。

于 2013-07-07T21:41:14.037 回答