有什么方法可以从基类的动态列表中创建一个类吗?
def dynamic_class_creator(base, base2):
class Derived(base, base2):
pass
return Derived
class Mixin1(object):
def greet(self):
print ("Howdy!")
class Mixin1a(object):
def insult(self):
print ("You have a lot to learn.")
class Mixin2(object):
def insult(self):
print ("Idiot!")
polite = dynamic_class_creator(Mixin1, Mixin1a)()
polite.greet()
polite.insult()
complex = dynamic_class_creator(Mixin1, Mixin2)()
complex.greet()
complex.insult()
这按预期工作:
Howdy!
You have a lot to learn.
Howdy!
Idiot!
但我不知道如何从任意长度的列表中分配这些碱基:
def dynamic_class_creator(*bases):
class Derived(*bases):
pass
return Derived
(...)
给出:
File "../test2.py", line 4
class Derived(*bases):
^
SyntaxError: invalid syntax
编辑
一个建议的解决方案:
def dynamic_class_creator(*bases):
class Derived(bases):
pass
return Derived
(...)
给予:
Traceback (most recent call last):
File "../test2.py", line 20, in <module>
polite = dynamic_class_creator(Mixin1, Mixin1a)()
File "../test2.py", line 4, in dynamic_class_creator
class Derived(bases):
TypeError: Error when calling the metaclass bases
tuple() takes at most 1 argument (3 given)
最佳答案
您可以使用 type()
构造函数的三参数形式。引用the documentation ,“使用三个参数,返回一个新类型对象。这本质上是 class
语句的动态形式。”
# TESTED with Python3
def dynamic_class_creator(*bases):
return type('Derived', bases, {})
上面的问题是你丢失了class
语法。例如,这使得向 Derived
添加方法变得困难。
您可以保留类声明的良好语法,并且仍然使用 metaclass 修改对 type()
的调用。 .
这是一个完整的示例,演示了 metaclass=
、type()
以及常规基类和混合基类的使用。
# TESTED with Python3
def dynamic_class_creator(*mixins):
def metaclass(name, bases, members):
return type(name, bases + mixins, members)
class Derived(BaseClass, metaclass=metaclass):
def praise(self):
print("Good job!")
return Derived
class BaseClass(object):
def goodbye(self):
print("Goodbye!")
class Mixin1(object):
def greet(self):
print("Howdy!")
class Mixin1a(object):
def insult(self):
print("You have a lot to learn.")
class Mixin2(object):
def insult(self):
print("Idiot!")
polite = dynamic_class_creator(Mixin1, Mixin1a)()
polite.greet()
polite.insult()
polite.praise()
polite.goodbye()
complex = dynamic_class_creator(Mixin1, Mixin2)()
complex.greet()
complex.insult()
您可以将任意关键字传递给元类函数。考虑这个例子:
# TESTED with Python3
def mixin_metaclass(name, bases, members, mixins):
return type(name, bases+mixins, members)
def dynamic_class_creator(*mixins):
class Derived(metaclass=mixin_metaclass, mixins=mixins):
pass
return Derived
最后,请注意,以上所有示例均使用 Python3 进行测试。这是Python2版本:
# TESTED with Python2
def dynamic_class_creator(*mixins):
def metaclass(name, bases, members):
return type(name, mixins+bases, members)
class Derived(object):
__metaclass__ = metaclass
def praise(self):
print("Good job!")
return Derived
关于python - 从动态创建的基列表创建类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49948455/