具有继承的动态类和方法实例化

时间:2017-04-21 18:52:25

标签: python python-3.x inheritance dynamic

我的要求是根据特定的字符串动态实例化一个类。这里的问题是新类在其他一些类上有继承。问题是我无法看到从Inherited类执行代码。

我试图通过让一个类SystemConfigure来实现这一点,它将根据dict中给出的参数调用特定的类。在我的代码中,我动态调用超级类,它继承了Base类的函数。我没有看到Base类中的代码被执行。

请让我知道如何做到这一点。

代码

class SystemConfigure():

    def __init__(self,snp_dict):
        dict = snp_dict
        osname = dict['osname']
        protocol = dict['protocol']
        module = protocol
        func_string = osname + "_" + protocol + "_" + "Configure"
        print ("You have called the Class:", module, "and the function:", func_string)
        m = globals()[module]
        func = getattr(m, func_string)
        func(dict)

class Base():

    def __init__(self):
        pass
        print("BASE INIT")

    def Unix_Base_Configure(dict):
        print ("GOT IN THE UNIX BASE CLASS FUNCTION")

    def Linux_Base_Configure(dict):
        print("GOT IN THE LINUX BASE CLASS FUNCTION")

class Super(Base):

    def __init__(self):
        dict = dict
        Base.__init__(self)
        Base.Unix_Base_Configure(dict)

    def Unix_Super_Configure(dict):
        print ("GOT IN THE UNIX SUPER CLASS FUNCTION", dict)

n = SystemConfigure({'protocol':'Super','osname':'Unix','device':'dut'})

输出

You have called the Class: Super and the function: Unix_Super_Configure
GOT IN THE UNIX SUPER CLASS FUNCTION {'protocol': 'Super', 'osname': 'Unix', 'device': 'dut'}

期望

我期待打印出“在UNIX BASE CLASS FUNCTION中出现GOT”错误。需要在“超级类功能中的GOT”消息之前打印输出。

2 个答案:

答案 0 :(得分:0)

这通常是Python中元类的工作 快速解释,元类可用于定义“如何”创建一个类 查看文档或查找“python元编程教程”以获取有关该主题的更多信息(So: What are Python metaclasses useful for?

class BaseMetaClass(type):
    def __new__(meta, name, bases, dct):
        return super(BaseMetaClass, meta).__new__(meta, name, bases, dct)

    def __init__(cls, name, bases, dct):
        super(BaseMetaClass, cls).__init__(name, bases, dct)

    def __call__(cls, *args, **kwds):
        if args and isinstance(args[0], dict):
            if 'osname' in args[0]:
                cls.osname = args[0]['osname']
            else:
                cls.osname = "undefined os"

            cls.base_configure = "GOT IN THE %s BASE CLASS FUNCTION" % cls.osname.upper()
        return type.__call__(cls, *args, **kwds)


class SystemConfigure(metaclass=BaseMetaClass):
    def __init__(self, snp_dict):
        print (self.base_configure)

n = SystemConfigure({'protocol':'Super','osname':'Unix','device':'dut'})
n = SystemConfigure({'protocol':'Super','osname':'Linux','device':'dut'})
n = SystemConfigure({'protocol':'Super','device':'dut'})

返回:

GOT IN THE UNIX BASE CLASS FUNCTION
GOT IN THE LINUX BASE CLASS FUNCTION
GOT IN THE WINDOWS BASE CLASS FUNCTION

答案 1 :(得分:0)

您需要将某些方法定义为@staticmethods,因为它们没有self参数(或需要一个)。以下是您的代码# ADDED

我还改变了传递给SystemConfigure()的字典参数的处理方式,因此它现在利用Python关键字参数传递来创建一个字典来传递它,但是这个更改并不是严格要求的。

class SystemConfigure():
    def __init__(self, **kwargs):  # CHANGED - argument snp_dict into **kwargs
        # dict = snp_dict  # REMOVED - no longer needed
        osname = kwargs['osname']
        protocol = kwargs['protocol']
        module = protocol
        func_string = osname + "_" + protocol + "_" + "Configure"
        print ("You have called the Class:", module, "and the function:", func_string)
        m = globals()[module]
        func = getattr(m, func_string)
        func(kwargs)

class Base():
    def __init__(self):
        pass
        print("BASE INIT")

    @staticmethod  # ADDED
    def Unix_Base_Configure(dict):
        print ("GOT IN THE UNIX BASE CLASS FUNCTION")

    @staticmethod  # ADDED
    def Linux_Base_Configure(dict):
        print("GOT IN THE LINUX BASE CLASS FUNCTION")

class Super(Base):
    def __init__(self):  # THIS IS NEVER CALLED
#        dict = dict  # REMOVED - don't know what this is all about...
        Base.__init__(self)
        Base.Unix_Base_Configure(dict)  # why is a type being passed?

    @staticmethod  # ADDED
    def Unix_Super_Configure(dict_):
        print ("GOT IN THE UNIX SUPER CLASS FUNCTION", dict_)

# Changed how dictionary argument is created into a more (IMO) readable form (optional)
n = SystemConfigure(protocol='Super', osname='Unix', device='dut')

输出:

You have called the Class: Super and the function: Unix_Super_Configure
GOT IN THE UNIX SUPER CLASS FUNCTION {'protocol': 'Super', 'osname': 'Unix', 'device': 'dut'}