[英]python multiple nested classes
这看起来像类继承,但我认为不是,并且必须有一种简单的方法来进行以下操作。 看一下这个简单的代码:
class Land:
def __init__(self):
print "a new Land"
self.farms = []
def addfarm(self):
self.farms.append(Farm())
class Farm:
def __init__(self):
print "a new farm"
self.animals = []
def addanimal(self,name):
self.animals.append(Animal(name))
class Animal:
def __init__(self, name):
print "hi, I am %s" % name
self.name = name
USA = Land()
USA.addfarm()
USA.farms[0].addanimal('George')
USA.farms[0].addanimal('Martin')
USA.addfarm()
USA.farms[1].addanimal('Polly')
USA.farms[1].addanimal('Ralph')
有没有一种简单的方法来获取所有动物而不做?:
for eachfarm in USA.farms:
for each in eachfarm.animals:
print each.name
我之所以这样问是因为,例如,如果用户要向服务器场0添加新的George,我希望很快就能说出这个名字。 我还可以快速运行一个功能,该功能为我提供土地或所有农场中的所有动物。 我应该为所有这些编写函数还是Python拥有自己的函数?
我也想知道我的嵌套类结构是否不正确,并最终导致问题。
例如,假设我有一个函数,给定动物告诉我它的完美食物组合。 我希望能够在所有动物上运行该功能并将其写回到它们的对象中。 如果它们嵌套,恐怕功能可能会混淆!
谢谢!
像这样使用嵌套类非常好,并且根本不涉及继承。 但是,您可能希望选择略有不同的数据结构。
您说在每个农场中,您只希望能够拥有每个名字的一只动物。 但是,您使用列表来存储它们。 列表允许您在其中包含任意数量的同名动物,因此添加另一只动物时,您需要自己进行一次检查。
但是,您可以使用dict
。 dict是将键与值链接在一起的无序数据结构。 在您的情况下,您可以使用动物的名称作为键,并使用Animal
对象作为值。 因为在内部, dict
是哈希表,所以可以在恒定时间内(与使用循环的线性时间相比)检查键是否存在。
示例代码可能如下所示:
class Land:
def __init__(self):
print "a new Land"
self.farms = []
def addfarm(self):
self.farms.append(Farm())
class Farm:
def __init__(self):
print "a new farm"
self.animals = {}
def addanimal(self,name):
if not name in self.animals:
self.animals[name] = Animal(name)
return True
return False
class Animal:
def __init__(self, name):
print "hi, I am %s" % name
self.name = name
USA = Land()
USA.addfarm()
USA.farms[0].addanimal('George')
USA.farms[0].addanimal('Martin')
USA.addfarm()
USA.farms[1].addanimal('Polly')
USA.farms[1].addanimal('Ralph')
这样可以防止您将两个相同名称的动物添加到一个服务器场,并根据是否可以将动物添加到服务器场来返回布尔值。
为了使所有农场中的所有动物都需要嵌套循环。 但是,启用对象本身的迭代会更好。 如果您执行以下操作:
class Land(object):
def __init__(self):
print "a new Land"
self.farms = []
def addfarm(self):
self.farms.append(Farm())
def __iter__(self):
for farm in self.farms:
yield farm
class Farm(object):
def __init__(self):
print "a new farm"
self.animals = {}
def addanimal(self,name):
if not name in self.animals:
self.animals[name] = Animal(name)
return True
return False
def __iter__(self):
for name, animal in self.animals.iteritems():
yield animal
class Animal(object):
def __init__(self, name):
print "hi, I am %s" % name
self.name = name
然后,您可以:
for farm in USA:
for animal in farm:
pass #do something here
根据您的评论,您还希望能够执行land.getAllAnimals()
和farm.getAllAnimals()
。 后者很容易实现,因为farm
是所有动物的迭代器。 如果您想要一个列表,可以简单地调用list(farm)
。
对于land.getAllAnimals()
,有两个不错的选择。 两者都将添加到先前的声明中。
class Land(object): def getAllAnimals(self): for farm in self: for animal in farm: yield animal
选项2
from itertools import chain class Land(object): def getAllAnimals(self): return chain(*self)
两者都将返回所有动物的迭代器。 要将它们投射到列表中,只需在它们上调用list
。 前者更容易理解,但后者更简洁,我认为更好。
嵌套循环没有任何问题,而这只是做到这一点的方法。 您可能希望研究一种更具声明性的方法,或者可能希望以不同的方式存储数据,但这仅是实现细节,主要是个人喜好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.