我必须创建给定类的许多子类。我不想手动这样做(因为课程数量可能很大。我有一个几乎可行的解决方案......几乎 - 看看下面的例子,请告诉我我做错了什么。
ZOO_CLASSES字典为每个动物(字符串)保存(并且必须保持)我们创建的类。
最终解决方案必须使用Animal基类的继承,并且必须使用
创建每种动物物种的对象one_lion = Lion()
或
one_lion = ZOO_CLASSES['Lion']()
我发现的问题是(因为测试会显示你是否运行它们 - 而不是“真,假,这是狮子,这是熊”我得到“真,真,这是鹦鹉,这是Parrot“。我认为问题在于,当调用构造函数并评估其参数(self和i)时,它需要最后指定的值(i =”Parrot“)。但是,我创建的对象属于正确的类类型而我没有看到任何其他意外行为。
顺便说一句,我是Python新手。 :)
class Animal:
def __init__(self, name):
self.name = name
def __str__(self):
return "This is " + self.name
def __eq__(self, other):
return self.name == other.name
ZOO = ['Lion', 'Bear', 'Parrot'] # list with many animals
ZOO_CLASSES = {}
for i in ZOO:
ZOO_CLASSES[i] = type(i, (Animal,), dict(__init__=lambda self: Animal.__init__(self, i)))
# or even tried:
for i in ZOO:
def constructor(self):
Animal.__init__(self, i)
ZOO_CLASSES[i] = type(i, (Animal,), dict(__init__=constructor))
# each time it creates a different function (as should be) but the value of i stays to the last one in the list:
# tests:
print(ZOO_CLASSES["Lion"]() == ZOO_CLASSES["Lion"]()) # True
print(ZOO_CLASSES["Lion"]() == ZOO_CLASSES["Bear"]()) # False
print(str(ZOO_CLASSES["Lion"]())) # This is Lion
print(str(ZOO_CLASSES["Bear"]())) # This is Bear
# i.e. all times we call these classes (their constructors) - i gets evaluated as "Parrot" (last element of ZOO list)
###################
# I don't want to do this (because imagine if the list ZOO is really long,
# manually typing it would be stupid):
class Lion(Animal):
def __init__(self):
Animal.__init__(self, "Lion")
class Bear(Animal):
def __init__(self):
Animal.__init__(self, "Bear")
class Parrot(Animal):
def __init__(self):
Animal.__init__(self, "Parrot")
答案 0 :(得分:0)
问题是i
中的lambda
变量仅在您创建循环中定义的类的实例时才会被计算。此时循环将结束,i
将设置为列表中的最后一项 - Parrot
。
您应该将i
传递给lambda:
ZOO_CLASSES[i] = type(i,
(Animal,),
dict(__init__=lambda self, i=i: Animal.__init__(self, i)))
^
演示:
>>> class Animal:
... def __init__(self, name):
... self.name = name
...
>>> ZOO = ['Lion', 'Bear', 'Parrot']
>>> ZOO_CLASSES = {}
>>> for i in ZOO:
... ZOO_CLASSES[i] = type(i, (Animal,), dict(__init__=lambda self: Animal.__init__(self, i)))
...
>>> i
'Parrot'
>>> ZOO_CLASSES["Lion"]().name
'Parrot'
>>> for i in ZOO:
... ZOO_CLASSES[i] = type(i, (Animal,), dict(__init__=lambda self, i=i: Animal.__init__(self, i)))
...
>>> ZOO_CLASSES["Lion"]().name
'Lion'
另外,感谢@ BrenBarn的评论,请在此处查看更好的解释:Python lambda closure scoping。
希望有所帮助。