【问题标题】:referencing objects by name as attributes [closed]按名称引用对象作为属性[关闭]
【发布时间】:2019-01-26 06:37:52
【问题描述】:

是否有充分的理由将对象列表存储为“子属性”?在下面的示例中,我将几个动物对象存储在 animals 属性下的 Zoo 中,例如 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

【问题讨论】:

  • 这实际上是我工作场所标准的一部分,我无法确定这是好的还是坏的做法,但我可以说的是,如果您打算添加更多“子- attributes" ,例如,您有一种特定类型的鸟,并且您想要存储它的爪子大小,这将在 num_legs 下抽象出来并在其上扩展。所以你会有 zoo.animals.bird.num_legs.talon_size ,这可能会变得很混乱,我确实看到很多,但是如果你不希望很快添加它,我从来没有看到它有什么问题。
  • 这只是不必要的,并没有多大帮助

标签: python oop attributes coding-style


【解决方案1】:

在我看来,这样做会使您的代码难以调试、不灵活且不可读。这是个坏主意。如果发生以下情况会发生什么:

  1. 您有一个包含空格的动物名称?比如“电鳗”?
  2. 如果你想迭代动物,你必须这样做
    for name in vars(obj):
        print(getattr(obj, name))
    
    • 本质上,您可能必须重新实现所有标准容器函数,例如插入、添加、删除、过滤等,或者使用非常不直观的语法。
  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

【讨论】:

    猜你喜欢
    • 2019-05-14
    • 2010-09-25
    • 2014-03-01
    • 2017-05-09
    • 2014-11-01
    • 1970-01-01
    • 2013-05-30
    • 2013-10-18
    相关资源
    最近更新 更多