从库函数返回的Cast对象是Python中的继承类型

时间:2013-06-12 22:30:19

标签: python inheritance

我正在使用的库有一个返回A类对象的函数。

a = the_lib.lib_function()  # returns an object of type A

我有一个继承自A.

的班级B.
class B(A):
    def my_method(self):
        print "This is Travis's class"

我希望B的构造函数调用库函数并包装返回的A对象。我看到了这样做的另一个问题的答案:

class B(A):
    def __init__(self):
        a = the_lib.lib_function()
        self.__dict__ = a.__dict__

    def my_method(self):
        print "This is Travis's class"

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

不是通过尝试从A继承来添加功能,而是A the_lib.lib_function()返回的import types def my_method(self): print "This is Travis's class" def B(): a = the_lib.lib_function() a.my_method = types.MethodType(my_method, a) return a 实例。例如:

A

这将为您提供一个函数,您可以像类一样使用该函数返回the_lib.lib_function()返回的my_method实例,但这些实例还将包含{{1}}。

答案 1 :(得分:1)

只是将B未提供给A的所有属性访问转发到您的目的吗?即像这样:

class B(object):

    def __init__(self):
        self.__a = the_lib.lib_function()

    def __getattr__(self, name):
        return getattr(self.__a, name)

    # maybe define __setattr__ too, and other __magic__ methods

    def my_method(self):
        # ...

尽管如此,这有几点需要注意。例如,B无法从A继承,这将阻止检查实例。此外,大多数__magic__方法也需要手动换行。

答案 2 :(得分:1)

以下是您尝试做的一些替代方案。


如果您只需要my_method来访问A实例的属性,则无需执行任何操作。 Python没有“私有属性”;通过self参数访问属性与通过任何其他参数访问属性之间没有区别。所以:

def my_method(a):
    a.state.count += 1
    print "This is Travis's class"
a = the_lib.lib_function()
my_method(a)

如果你真的想把这个方法作为绑定方法附加到a,那么你可以这样做而不必担心类:

a = the_lib.lib_function()
a.my_method = types.MethodType(my_method, a, type(a))

如果你确实需要包装A实例,那么通过委托而不是继承来做它通常会更好。是否通过静态委派所需的方法来执行此操作,在类定义之后动态构建委派方法,在构造时动态构建它们,或者仅使用__getattr__动态执行它取决于您的实际需要。


如果您希望B充当A的子类,即使它不是A,也可以使用ABCs来欺骗isinstance等。


或者您甚至可以将B实例转换为A实例(例如,通过更改其__class__) - 但请记住,这将使其使用A的大多数dunder方法的实现(包括{{1} })。


如果你真的希望B成为一个子类,你可以编写一个复制属性的__getattr__构造函数(或类方法替代构造函数)。同样,您可以使用一组静态属性或动态执行此操作(只需记住__init__不处理__dict__,动态__slots__属性,__getattr__和类似假属性,从内置/扩展类继承的一些属性等。)。


那么,哪一个是对的?

如果不知道你实际想要完成什么,就不可能回答这个问题。在某些情况下,所有这些都是正确的,尽管其中一些比其他情况更少。