按名称作为属性引用对象

2024-10-06 12:33:33 发布

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

是否有充分的理由将对象列表存储为“子属性”?在下面的示例中,我将几个动物对象存储在动物园的animals属性下,例如zoo.animals.<animal object referenced by name>。这种语法使访问存储动物的属性变得更容易,我想知道这种结构是否有我尚未考虑的缺点:

class Animal(object):
    def __init__(self, name, num_legs, furry):
        self.name = name
        self.num_legs = num_legs
        self.furry = furry

class ObjAsAttributes(object):
    def __init__(self, **kwargs):
        for k,v in kwargs.items():
            setattr(self, k, v)

class Zoo(object):
    def __init__(self, animals):
        self.name = 'my zoo'
        self.hours = '8am-6pm'
        animals = {animal.name:animal for animal in animals}
        self.animals = ObjAsAttributes(**animals)




animal_list = [Animal(name='bird', num_legs=2, furry=False),
               Animal(name='giraffe', num_legs=4, furry=True),
               Animal(name='octopus', num_legs=8, furry=False)]

zoo = Zoo(animal_list)
zoo.animals.bird.num_legs
# returns 2

Tags: 对象nameself属性objectinitdefnum
1条回答
网友
1楼 · 发布于 2024-10-06 12:33:33

在我看来,这样做会使您的代码难以调试、不灵活和不可读。这是个坏主意。例如,如果:

  1. 你有一个包含空格的动物名字吗?比如“电鳗”?你知道吗
  2. 如果你想在动物身上迭代,你必须这样做
    for name in vars(obj):
        print(getattr(obj, name))
    
    • 本质上,您可能需要重新实现所有标准的容器函数,例如insert、add、delete、filter等,或者使用非常不直观的语法。你知道吗
  3. 你将如何合并或过滤与另一个动物园?如果需要,也没有办法对这些值进行排序。你知道吗

属性用于“保存数据”或“描述建模对象的特征”。你应该把它们只用于那个目的。


由于您主要寻求快速方便的访问,请使用dictOrderedDict

class Animal(object):
    def __init__(self, name, num_legs, furry):
        self.name = name
        self.num_legs = num_legs
        self.furry = furry

class Zoo(object):
    def __init__(self, animals):
        self.name = 'my zoo'
        self.hours = '8am-6pm'
        self.animals = {animal.name:animal for animal in animals}

animal_list = [Animal(name='bird', num_legs=2, furry=False),
               Animal(name='giraffe', num_legs=4, furry=True),
               Animal(name='octopus', num_legs=8, furry=False)]

zoo = Zoo(animal_list)
zoo.animals['bird'].num_legs
# returns 2

相关问题 更多 >