Adding a method to metaclass works perfectly in the below example.
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()
The below example doesn't work and I have no idea why. It simply doesn't recognise self in the parsed function and a TypeError occurs.
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)
First of all: You are not creating a metaclass, you are creating regular classes. type()
is the (base) metaclass here, calling it creates a new class object (the same type of object that a class
statement produces).
The first type()
call is essentially equivalent to:
class TypeTest(Test)
triple = triple
quadruple = quadruple
and the second example is the same as:
class Truck(Vehicle)
wheels = 4
door = True
load = 100
check_load = check_load
You forgot to create an instance of your Truck
class:
Truck.check_load(10)
This leaves the check_load()
function with nothing to bind to, there is no self
.
In your first example you did create an instance:
TypeTest(2).quadruple()
Notice the call, passing in 2
.
Create an instance for self
to be bound to:
Truck(4, True).check_load(10)
If you wanted your class to not need arguments to create an instance, you'll need to provide a different __init__
method too, one that overrides the Vehicle.__init__
method:
def init(self): pass
Truck = type('Truck', (Vehicle,), dict(
wheels=4,door=True, load=100,
check_load=check_load, __init__=init))
Now you can create the instance without arguments:
Truck().check_load(10)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.