0

I am making a simple Entity Component System in python using dictionaries (I heard they have better performance somehow), but I didn't wanted access the data like foo['bar']['x'], and wanted to access it more like foo.bar.x (just personal preference)

So I made this code

class Entity(dict):
    def __init__(self, dictionary={}):
        super().__init__(dictionary)

    def __getattr__(self, attribute):
        return self[attribute]

foo = Entity([('PositionComponent', {'x': 0, 'y': 0})])

So, I can access the PositionComponent as foo.PositionComponent but I cant access the x value as foo.PositionComponent.x

How could I make it work? And is there a better way to make what I've already made?


UPDATE

I made three versions of the same ECS in python

  1. Using Entity classes without extending dict foo.component(bar).x (for loop in foo.component)
  2. Using Entity classes extending dict foo['bar']['x']
  3. Using Entity classes extending dict and accessing components with custom __getattr__ foo.bar.x

Using a particle system, with 133 particles on screen at any time, as test I got the FPS of each ECS Particle System Used

This are the results:

  1. FPS around 750
  2. FPS around 1050
  3. FPS around 500

So this proves that using custom __getattr__ makes the code run 2x slower than using normal dicts

Max particles on screen
enter image description here
(left: FPS, Right Particles)
(Color disabled, circle gets drawn even with radius 0)
(12000 to reach 30 FPS)

1 Answer 1

1

You can't access the x value because it belongs to a dict instance, not a Entity one. A possible workaround would be to only use Entity.

Also, since you're inheriting from dict you can use **kwargs for building your objects.

class Entity(dict):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def __getattr__(self, attribute):
        return self[attribute]

foo = Entity(PositionComponent=Entity(x=0, y=1))
print(foo.PositionComponent.x)
>>> 0
Sign up to request clarification or add additional context in comments.

3 Comments

if I use kwargs it gives this error TypeError: __init__() takes 1 positional argument but 2 were given. The first part works fine tho
@Nath Can you share how you've used it?
oh, I spotted the problem, I was declaring the entity as i've done before Entity([('PositionComponent', {'x': 0, 'y': 0})]), when I used Entity(PositionComponent = Entity(x=0,y=1)) it worked

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.