question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Dynamically accessing attributes of provided objects.

See original GitHub issue

Hi, I recently needed to access an attribute of a provided object for constructing a new object. A minimal example would look like this

import random

from dependency_injector import containers, providers


class B:
    def __init__(self):
        self.val = random.randint(0, 10)

    def __repr__(self):
        return f"B({self.val})"


class A:
    def __init__(self, b_val: int):
        self.b_val = b_val

    def __repr__(self):
        return f"A({self.b_val})"

naively I tried to do

class MyContainer(containers.DeclarativeContainer):
    b = providers.Singleton(B)
    a = providers.Singleton(A, b.val)


def main() -> None:
    container = MyContainer()
    print(container.b())
    print(container.a())


if __name__ == "__main__":
    main()

which does not work, because of AttributeError: 'dependency_injector.providers.Singleton' object has no attribute 'val'.

I was able to work around this, by using

class MyContainer(containers.DeclarativeContainer):
    b = providers.Singleton(B)
    b_val = providers.Callable(getattr, b, "val")
    a = providers.Singleton(A, b_val)

However, I thought that it would be nice if dependency_injector would provide this behavior out of the box.

My attempts at implementing a provider that has this behavior look like

class AttributeFactory(providers.Provider):

    __slots__ = ('_factory',)

    def __init__(self, *args, **kwargs):
        self._factory = providers.Factory(*args, **kwargs)
        super().__init__()

    def __getattr__(self, item):
        return providers.Callable(getattr, self._factory, item)

class MyContainer(containers.DeclarativeContainer):
    b = AttributeFactory(B)
    a = providers.Singleton(A, b.val)

However, this fails with TypeError: __init__() takes at least 1 positional argument (0 given) because of some copying, that I can not really interpret.

I would be interested in hearing thoughts on this or if there are other ways to achieve this kind of attribute access.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
JarnoRFBcommented, Aug 20, 2020

@rmk135 Glad I could contribute some idea. I never heard about TRIZ, but it sounds like an interesting read!

I have it working. Productizing it will take some time. I would like to get all this well covered with tests.

Great, let me know if I can contribute something. I believe the feature will make dependency injector extremely flexible, lowering the barrier for people adopting it.

0reactions
JarnoRFBcommented, Aug 21, 2020

@rmk135 I am amazed by the speed you implemented this. Thanks a lot!

Read more comments on GitHub >

github_iconTop Results From Across the Web

how to read object attribute dynamically in java?
My question is I can pass various object in method(), is there any way I can access the attribute of the differnt object...
Read more >
How to Dynamically Access Object Property Using Variable in ...
Answer: Use the Square Bracket ( [] ) Notation​​ There are two ways to access or get the value of a property from...
Read more >
Dynamically Accessing Objects in Java - Kennemersoft
Dynamically accessing objects is accessing properties and methods of objects with property names and method names that are not known at compile time...
Read more >
Dynamic Attributes in Python - GeeksforGeeks
Dynamic attributes in Python are terminologies for attributes that are defined at runtime, after creating the objects or instances.
Read more >
Creating and Using Dynamic Objects (C# and Visual Basic)
To reference the id attribute of the HTML element <div id="Div1"> , you first obtain a reference to the <div> element, and then...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found