【问题标题】:Object instance as a member of a list --> Is this "pythonic"? Is this lege artis? [closed]作为列表成员的对象实例 --> 这是“pythonic”吗?这是乐理吗? [关闭]
【发布时间】:2019-09-15 21:26:28
【问题描述】:

我想听听您对此代码的意见或建议:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


# Defines the class (Element) that will be used in the Container
class Element:
    def __init__(self, address):
        # The address is the identifier for this element
        self._address = int(address)

    def theaddress(self):
        # Getter for the address
        return self._address

    def __eq__(self, other):
        # This function will be called if we like to check if this instanse is already a
        # member of the container instance
        print("A __eq__ called: %r == %r ?" % (self, other))
        return self._address == other._address


# Defines the class (Container) which holds n instances of Element class
class Container:
    def __init__(self):
        # Basically it is a list
        self._listcontainers = list()

    # If we like to append a new element instance, we have to check if new one is already available
    # with the same address. So we like to never had the same address twice or more times!
    def appendcontainer(self, possibleElement: Element = Element(1)):
        # Calls the __eq__ element of the Element class to check if this one (with exactly this address) is already present
        if possibleElement in self._listcontainers:
            # If the possibleElement is in the container list
            print('Address %i of this element %s is already existing.' % (possibleElement.theaddress(), possibleElement))
            return False
        else:
            # If possobleElement is new append it to the containerlist
            self._listcontainers.append(possibleElement)
            print('Added element: %s with address: %i' % (possibleElement, possibleElement.theaddress()))
            return True

    # Returns the available elements in the containers
    def lengthcontainers(self):
        return len(self._listcontainers)


def main():
    # List of containers
    myContainer = Container()

    # New element with address 1
    newElement1 = Element(1)
    myContainer.appendcontainer(newElement1)

    # New element with address 2
    newElement2 = Element(2)
    myContainer.appendcontainer(newElement2)

    # New element with address xyz
    newElement3 = Element(2) # You can play with the addresses...
    myContainer.appendcontainer(newElement3)

    print('Available elements: %i' % myContainer.lengthcontainers())


if __name__ == "__main__":
    main()

现在:

  • 我有一个元素类,它代表一些数据的抽象。它本身也会包含一些逻辑作为私有方法......
  • 我有一个包含 n 个元素实例的类(本例中为 Container)。
  • 我需要防止添加具有相同属性的元素。在本例中 - 相同的地址。

问题:

  • 我想知道这是否是识别元素的最先进技术?
  • 也许有更好的方法在 Python 3 中执行此操作?
  • 尤其是__eq__ 函数对我来说非常有趣。因为,_address 应该是一个私有变量,我在other._address 处收到警告-->“访问受保护的成员 _address of a class...”。我需要在这里考虑什么吗?

任何意见或建议都会对我很有帮助。实际上我只是在做原型设计,但它应该是在这种情况下保存一些数据的真实项目的基础。

【问题讨论】:

  • 这可能更适合在codereview.stackexchange.com中提问
  • 你能用set() 代替吗?一个集合包含独特的元素。
  • Container 可以替换为set()Element 可以替换为namedtuple。 IMO 使用无处不在的数据结构和模式使代码更易于阅读和维护。
  • @ruohola 是的,你是对的。我不知道这个论坛。谢谢。

标签: python python-3.x oop design-patterns


【解决方案1】:

我认为魔术方法(如__eq____le__ 等)是允许的(就代码风格而言)使用other 对象的受保护成员,所以我会忽略警告。

至于附加,如果可能的话,我建议使用set 而不是list。仅存储不同的元素是 set 的工作,您无需检查元素的存在,set 会为您完成。不要忘记为您的Element 类实现__hash__ 方法:

class Element:
    ...

    def __hash__(self):
        return hash(self._address)

    def __eq__(self, other):
        return self._address == other._address

【讨论】:

  • 很好用。但是如果我添加一个已经在集合中的元素,我没有得到返回值(假)?这是正确的吗?
  • 正确。因此,如果您需要它返回 False,您可以事先手动检查集合中的元素。在 Python 中,set 被实现为 HashSet,所以这个检查将在 O(1) 中进行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多