繁体   English   中英

python多个嵌套类

[英]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() ,有两个不错的选择。 两者都将添加到先前的声明中。

选项1
 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM