简体   繁体   中英

any way of iterating over __slots__ and dynamically assign values?

I'm making a framework for an agent based model and I have a class called agents. Since there's going to be thousands of agents in the simulation, I want to use the __ slots__, which will replace the default __ dict__ and reduce memory consumption. I have my code structured so that it gets the agent's parameter from a data table and I want to assign the values stored in the table to an attribute with the table's header name.

If the following is the data table,

|  agent_name  |  location  |    attr1    |    attr2   |
|--------------|------------|-------------|------------|
|  agent smith |    NY      |  some value | some value |
|  Neo         |    NY      |  some value | some value |
| Morpheus     |    Zion    |  some value | some value |

then if I create the 3 agents, I want all of them to have a.agent_name, .location, .attr1, and.attr2 attributes.

# 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

I know you can use the.eval method inside the for loop, but I don't find that clean and I feel like there has to be a better way. I'm wondering if there's a way to iterate over the slots and assign value to each attributes.

A few pointers:

  • When using __slots__ you need to inherit from object . Python 2
  • A class should always be capitalized.
  • You can use setattr as Michael wrote in a comment.
  • It's called __slots__ not __slot__ .

Here's a working example based on your code:

# 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

Edit for comment: If I understand you correctly then I would do something like this to avoid polluting the global scope.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM