【问题标题】:Python: Detect if a class method is redefined/overloaded from the C APIPython:检测类方法是否从 C API 重新定义/重载
【发布时间】:2015-08-04 03:42:12
【问题描述】:

我目前正在编写嵌入 Python 的 C 代码以正确设置问题。因此,用户应该从定义一般结构的 Python 类中导出他自己的问题。作为最小的例子,我使用

class testbase(object):
    def __init__(self,name):
        self._name = name
    def method1(self):
        pass
    def method2(self):
        pass

作为基类。现在对于每个问题,都应该从此类中派生出自己的问题,例如

class test(testbase):
    def __init__(self,name):
        self._name = name
    def method1(self):
        print self._name 

method2 不是由用户定义的。现在我想从 C API 或至少在 Python 中检测派生类是否提供 method2 或者它是否从基类中使用。

第一个答案不像我那么精确,所以如果有一个测试类的实例

 T = test('test')

我想知道T.method2是在test中定义还是继承自testbase

【问题讨论】:

标签: python


【解决方案1】:

感谢@ZachGates,我利用他的想法将其扩展为适用于类和对象:

class Parent(object):
    def __init__(self):
        pass

    def parent_method(self):
        print('parent')

    @classmethod
    def parent_class_method(self):
        print('parent class method')

class Child(Parent):
    def __init__(self):
        pass

    def child_method(self):
        print('child')

    @classmethod
    def child_class_method(self):
        print('child class method')

def is_inherited_instance_method(test_object, method_name):
    """ 
    Gets the super object and looks up for it's method. 
    If the child has `method_name` atribute and parent doesn't,
    then method is new.
    """

    super_object = super(test_object.__class__, test_object)
    if hasattr(test_object, method_name) and not hasattr(super_object, method_name):
        # You can add extra checks, such as: callable() ...
        print('it is a new method: %s' % method_name)
    else:
        print('method is not new: %s' % method_name)

def is_inherited_class_method(test_cls, method_name):
    """ Does the same but only with Classes. """

    super_cls = super(test_cls, test_cls)
    if hasattr(test_cls, method_name) and not hasattr(super_cls, method_name):
        # You can add extra checks, such as: callable() ...
        print('it is a new class method: %s' % method_name)
    else:
        print('class method is not new: %s' % method_name)


parent = Parent()
child = Child()

is_inherited_instance_method(parent, 'parent_method')
is_inherited_instance_method(child, 'parent_method')
is_inherited_instance_method(child, 'child_method')

is_inherited_class_method(Parent, 'parent_class_method')
is_inherited_class_method(Child, 'parent_class_method')
is_inherited_class_method(Child, 'child_class_method')

输出是:

it is a new method: parent_method
method is not new: parent_method
it is a new method: child_method

it is a new class method: parent_class_method
class method is not new: parent_class_method
it is a new class method: child_class_method

【讨论】:

    【解决方案2】:

    指定子类时,继承父类的所有方法。

    class A(object):
        def foo(self):
            pass
    
    class B(A):
        def bar(self):
            pass
    

    A 类只有一个方法:foo。而B 类有两个方法:创建的bar 方法和继承的foo 方法。

    你可以像这样检查一个方法是否被继承:

    >>> def inherited(cls, method):
    ...     if hasattr(cls, method) and hasattr(super(cls, cls), method):
    ...         return A.foo == B.foo
    ...     else:
    ...         return False
    ...
    >>> inherited(B, 'foo')
    True
    >>> inherited(B, 'bar')
    False
    

    【讨论】:

    • 我想检查该方法是否是继承的。
    • 编辑添加。 @Grisu
    • 仍然适用于类而不是类的实例。
    猜你喜欢
    • 2011-06-12
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 2010-09-13
    相关资源
    最近更新 更多