python多个嵌套类

2024-06-28 20:17:29 发布

您现在位置:Python中文网/ 问答频道 /正文

这看起来像类继承,但我认为不是这样,必须有一个简单的方法来完成下面的工作。看看这个简单的代码:

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

我问这个问题是因为,例如,如果用户想添加一个新的George到farm 0,我想很快就可以说这个名字已经被使用了。我还可以快速运行一个功能,让我所有的动物在土地上或所有农场。我应该为所有这些编写函数还是Python有自己的函数?你知道吗

我还想知道我的嵌套类结构是否不正确,最终是否会导致问题。你知道吗

例如,假设我有一个函数,给一个动物告诉我它的完美食物组合。我希望能够在我所有的动物身上运行这个函数,并写回它们的对象。如果它们是嵌套的,我担心函数可能会混淆!你知道吗

谢谢!你知道吗


Tags: 方法函数nameselfinitdefclassprint
2条回答

像这样使用嵌套类是非常好的,根本不涉及继承。但是,您可能希望选择稍微不同的数据结构。你知道吗

你说在每一个农场里,你只想拥有一个名字的动物。但是,您可以使用列表来存储它们。一个列表允许你在里面有尽可能多的同名动物,所以你需要在添加另一个动物时自己进行检查。你知道吗

但是,可以使用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。前者更容易理解,但后者更简洁,在我看来,更好。你知道吗

嵌套循环并没有错,这只是一种方法。您可能希望研究一种更具声明性的方法,或者希望以不同的方式存储数据,但这都只是实现细节,主要是品味问题。你知道吗

相关问题 更多 >