Property functions out of class

Viewed 83

Is there a way in Python to have something similar to properties, but out of a class?

Maybe it is duplicated, but I did not find a correct answer.

Here is an example where to solve:

config = {'a':1}
config_a = some_function(config, 'a')

config_a  # eval as 1
config['a'] = 2
config_a  # eval as 2

With class and properties, it would be easy, but note here I am force to work with 'a' outside a class.

Can modules have properties the same way that objects can? does not solve the issue, as it involves modules and does not solve the issue above.

More context

I have a Flask application, which needs uses a non-flask plugin. Therefore I have 2 separated config objects:

  • flask: app.config (dict)
  • extension: ext (object, not dict)

The application uses app.config to load generic configuration and other extensions configuration. I want to know if there is a simple way (not involving monkey patching) to have ext.config values pointing to app.config values, so I only have to handle one configuration file.

# extension.py
class Extension()
    def __init__(self):
        self.a = "value_1"

# fix.py to use extension flask way
class MyExtension()
    def init_app(self, app):
        app.ext = Extension()
        app.config.setdefault('a', default_a)
        app.ext.a = some_function(app.config, 'a')

Note in the example above, I do not have access to extension.py to change "a" into a property.

I could use monkey-patching to convert "a" into a property, but probably there is a simpler way.

1 Answers

Short answer

Pointers are not implemented in Python, therefore it is NOT possible. My thanks to @Robin Gertenbach for pointing me to Pointers in Python?

But

If you are lucky enough to fall in my context case, it is possible to extend the original class with properties. It does not solves the question, but you have to solve the problem in a different way:

# extension.py
class Extension()
    def __init__(self):
        self.a = "value_1"

# fix.py to use extension flask way
class Extension(extension.Extension):
    def __init__(self, app, *args, **kwargs):
        self.app = app
        super().__init__(*args, **kwargs)

    @property
    def a(self):
        return self.app.config['a']

    @a.setter
    def a(self, value):
        self.app.config['a'] = value

class MyExtension()
    def init_app(self, app):
        app.ext = Extension(app)

If the variable you are trying to point is not in a class, probably you can make a mix of the code above with Can modules have properties the same way that objects can?

Related