2017-04-21 67 views
0

我的需求是基於特定的字符串動態實例化一個類。在這裏捕捉到的是新類在其他類上有繼承。問題是我無法看到代碼從Inherited類中執行。帶繼承的動態類和方法實例化

我試圖通過有一個類SystemConfigure這樣做,它將根據字典中給出的參數調用特定的類。在我的代碼中,我動態地調用了繼承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基類FUNCTION」 要打印錯誤。輸出需要在「GOT IN THE SUPER CLASS FUNCTION」消息之前打印。

+1

你的代碼中有多處錯誤。你永遠不會實例化你的類,所以'__init__'都不會被調用。你的「配置」方法也不接受「自我」論證。 – BrenBarn

回答

0

這通常是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 
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'}