当一个类是从Python中的某个特定父类派生的时,有没有一种方法可以让代码运行?

2024-04-20 10:58:35 发布

您现在位置:Python中文网/ 问答频道 /正文

例如,如果我创建类Foo,然后派生子类Bar,我希望Foo的myCode()方法运行。你知道吗

class Foo(object):
    x = 0
    def __init__(self):
        pass
    def myCode(self):
        if(self.x == 0):
            raise Exception("nope")


class Bar(Foo):    #This is where I want myCode() to execute
    def baz(self):
        pass

这应该在类从基类Foo派生的任何时候发生。在Python中可以这样做吗?如果重要的话,我会使用python3。你知道吗

注意:在我的实际代码中,Foo实际上是一个抽象基类。你知道吗

编辑:我还需要访问myCode()中的派生类成员数据和方法。你知道吗


Tags: 方法selfifobjectfooinitdefexception
3条回答

希望此代码能帮助您:

class Foo:
    def myCode(self):
        print('myCode within Foo')
    def __init__(self):
        if type(self) != Foo:
            self.myCode()

class Bar(Foo):
    def __init__(self):
        super(Bar, self).__init__()
    def baz(self):
        pass

测试:

>>> 
>>> f = Foo()
>>> b = Bar()
myCode within Foo
>>> 

这样做有效:

class MyMeta(type):
    def __new__(cls, name, parents, dct):
        if name is not 'Foo':
            if 'x' not in dct:
                raise Exception("Nein!")
            elif 'x' in dct and dct['x'] == 0:
                raise Exception("Nope!")
        return super(MyMeta, cls).__new__(cls, name, parents, dct)

输出:

class Bar(Foo):
    x = 0
> Exception: Nope!

如果有人想评论这是否合适,这是我的特定用例:

class MagmaMeta(type):
    def __new__(cls, name, parents, dct):
        # Check that Magma instances are valid.
        if name is not 'Magma':
            if 'CAYLEY_TABLE' not in dct:
                raise Exception("Cannot create Magma instance without CAYLEY_TABLE")
            else:
                # Check for square CAYLEY_TABLE
                for row in CAYLEY_TABLE:
                    if not len(row) == len(dct['CAYLEY_TABLE']):
                        raise Exception("CAYLEY_TABLE must be a square array")
                # Create SET and ORDER from CAYLEY_TABLE
                dct['SET'] = set([])
                for rows in CAYLEY_TABLE:
                    for x in rows:
                        dct['SET'].add(x)
                dct['ORDER'] = len(dct['SET'])
        return super(MyMeta, cls).__new__(cls, name, parents, dct)

使用metaclass

class MetaClass:
    def __init__(cls, name, bases, dictionary):
        if name is not 'Parent':
            print('Subclass created with name: %s' % name)
        super().__init__(name, bases, dictionary)

class Parent(metaclass=MetaClass):
    pass

class Subclass(Parent):
    pass

输出:

Subclass created with name: Subclass

元类控制类本身的创建方式。子类从父类继承它的元类,因此当定义它时,代码就会运行。你知道吗

编辑:对于抽象基类的用例,我想您只需要将元类定义为ABCMeta的子类,但我没有测试它。你知道吗

相关问题 更多 >