【问题标题】:any way of iterating over __slots__ and dynamically assign values?任何迭代 __slots__ 并动态分配值的方式?
【发布时间】:2020-06-14 05:27:34
【问题描述】:

我正在为基于代理的模型创建一个框架,并且我有一个名为代理的类。由于模拟中将有数千个代理,我想使用 __slot__,它将替换默认的 __dict__ 并减少内存消耗。我对代码进行了结构化,以便它从数据表中获取代理的参数,并且我想将存储在表中的值分配给具有表头名称的属性。

如果下面是数据表,

|代理名 |位置 |属性 1 | attr2 | |---------------|------------|-------------|------- -----| |代理史密斯|纽约 |一些价值|一些价值| |新 |纽约 |一些价值|一些价值| |墨菲斯 |锡安 |一些价值|一些价值|

如果我创建 3 个代理,我希望它们都具有 .agent_name、.location、.attr1 和 .attr2 属性。

# illustration of what I want
header_of_table = ["agent_name", "location", "attr1", "attr2"]

class agent:
    __slots__ = header_of_table
    def __init__(self, values_in_row):
        # what I ideally want, I know this syntax doesnt work, but this is to get the idea across
        for slotted_attribute, value in zip(self.__slots__, values_in_row):
            self.slotted_attribute = value

我知道你可以在 for 循环中使用 .eval 方法,但我觉得不是很干净,我觉得必须有更好的方法。我想知道是否有一种方法可以遍历插槽并为每个属性分配值。

【问题讨论】:

  • 有“setattr”。
  • 应该读到这个:stackoverflow.com/questions/472000/usage-of-slots 例如,它说你的类需要从object 继承。也是__slots__ 不是__slot__
  • 如果我没记错的话,你不需要在 Python 3 中显式继承 object
  • @mandera 是的,我在第一段中有插槽,但其余的是插槽。我替换了所有这些错别字。

标签: python slots


【解决方案1】:

几点建议:

  • 当使用__slots__时,你需要从object继承。 Python 2
  • 类应始终大写。
  • 您可以使用 setattr,正如 Michael 在评论中所写的那样。
  • 它叫__slots__ 而不是__slot__

这是一个基于您的代码的工作示例:

# illustration of what I want
header_of_table = ["agent_name", "location", "attr1", "attr2"]

class Agent:
    __slots__ = header_of_table
    def __init__(self, values_in_row):
        for i, slot in enumerate(self.__slots__):
            self.__setattr__(slot, values_in_row[i])

agent = Agent(["foo", "bar", "yellow", "green"])
print(agent.agent_name, agent.location, agent.attr1, agent.attr2)

>>> foo bar yellow green

编辑评论: 如果我理解正确,那么我会这样做以避免污染全局范围。

slotheaders.py:

class SlotHeaders:
    __slots__ = ["agent_name", "location", "attr1", "attr2"]

agent.py:

from slotheaders import SlotHeaders

class Agent(SlotHeaders):
    def __init__(self, values_in_row):
        for i, slot in enumerate(self.__slots__):
            self.__setattr__(slot, values_in_row[i])

agent = Agent(["foo", "bar", "yellow", "green"])
print(agent.agent_name, agent.location, agent.attr1, agent.attr2)

【讨论】:

  • object 继承只是 Python 2 中的一件事。在 Python 3 中,这会自动发生,除非您需要与 Python 2 向后兼容(而且您可能不需要't, 现在)。
  • 我是从编辑器上复制粘贴的,所以我没有注意到我忘记将类名大写,感谢您指出这一点,我会确保更正它。
  • @Mandera 我对当前的答案很满意,但是 header_of_row 在全局范围内,如果我想限制范围,那么我需要将 Agent 类嵌套在函数中可以存储header_of_row。这个元函数的目的仅仅是将 header_of_row 分配给__slots__。这是我能想出的唯一限制范围的方法,有没有更好的方法将变量分配给__slots__?还是我应该创建一个新问题,因为它与原始问题不同?
  • @KukaiNakahata 编辑了我的答案,你怎么看?
  • @Mandera 这是一个优雅的解决方案,它比将它包装在一个函数中要好。谢谢你,这是一个很好的答案。
猜你喜欢
  • 2022-07-06
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多