2017-06-22 23 views
-1

向元類添加一個方法在下面的例子中可以很好地工作。元類和方法

class Test(object): 

    def __init__(self, x): 
     self.x = x 

    def double(self): 
     return self.x*2 

# method to add 
def quadruple(self): 
    return self.x*4 

# creating metaclass 
TypeTest = type('TypeTest', (Test,), {'triple': triple, 
             'quadruple': quadruple}) 

# prints 8 
TypeTest(2).quadruple() 

下面的例子不起作用,我不知道爲什麼。它只是無法識別解析函數中的self併發生TypeError。

class Vehicle(object): 
    def __init__(self, wheels, door=False): 
     self.wheels = wheels 
     self.door = door 

# method to add 
def check_load(self, x): 
    if x > self.load: 
     return "Load won't fit" 
    else: 
     return "Load will fit" 

# creating metaclass 
Truck = type('Truck', (Vehicle,), dict(wheels=4,door=True, load=100, 
             check_load=check_load)) 

# TypeError: check_load() missing 1 required positional argument: 'x' 
Truck.check_load(10) 
+5

您並未創建元類。你正在使用類型元類來生成一個普通類。 –

+0

你究竟在努力實現什麼? – jonrsharpe

+0

「在下面的例子中,向元類添加一個方法完美。」這是不可能的,因爲名稱'triple'沒有綁定任何東西,所以引用它會拋出一個'NameError'。 – jpmc26

回答

5

首先:你是不是創建元類,你正在創建普通班。 type()這裏是(基本)元類,它調用它創建一個新的類對象(與class語句生成的對象類型相同)。

第一type()通話基本上等同於:

class TypeTest(Test) 
    triple = triple 
    quadruple = quadruple 

和第二個例子是一樣的:

class Truck(Vehicle) 
    wheels = 4 
    door = True 
    load = 100 
    check_load = check_load 

你忘了創建Truck類的實例

Truck.check_load(10) 

這使得check_load()函數沒有什麼可綁定的,沒有self

在你的第一個例子中,你創建一個實例:

TypeTest(2).quadruple() 

通知通話,傳遞2

創建self實例綁定到:

Truck(4, True).check_load(10) 

如果你想你的類不需要參數來創建一個實例,你需要提供不同的__init__方法也一樣,一個覆蓋該Vehicle.__init__方法:

def init(self): pass 

Truck = type('Truck', (Vehicle,), dict(
    wheels=4,door=True, load=100, 
    check_load=check_load, __init__=init)) 

現在你可以不帶參數創建實例:

Truck().check_load(10)