2017-06-22 7 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() 

以下の例は機能しません。理由はわかりません。それは単に解析された関数で自己を認識せず、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

メタクラスを作成していません。 *あなたは正規のクラスを生成するために 'type'メタクラスを使用しています。 –

+0

*実際に*達成しようとしているのは何ですか? – jonrsharpe

+0

"メタクラスへのメソッドの追加は、以下の例では完全に機能します。" 'triple'という名前は何にも束縛されていないので、これは不可能です。そのため、その参照は' NameError'を投げます。 – jpmc26

答えて

5

まず第一に:あなたは、メタクラスを作成ないされ、あなたが通常のクラスを作成しています。 type()はここでの(基本)メタクラスです。新しいクラスオブジェクト(class文が生成するオブジェクトと同じ種類のオブジェクト)を作成します。

最初type()コールはと本質的に同等である:

class TypeTest(Test) 
    triple = triple 
    quadruple = quadruple 

及び第二の例と同じである:あなたのTruckクラスのインスタンスを作成するのを忘れ

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

Truck.check_load(10) 

これにより、check_load()関数はバインドすることなく機能しますが、selfはありません。 2に渡し、

TypeTest(2).quadruple() 

お知らせコール:あなたの最初の例で

あなたは、インスタンスを作成しました。

selfはにバインドするためのインスタンスを作成します。

Truck(4, True).check_load(10) 

インスタンスを作成するために、引数を必要としないためにあなたのクラスを望んでいた場合、あなたは、あまりにも優先されます1を異なる__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) 
関連する問題