3

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.

Alex Waygood
  • 6,304
  • 3
  • 24
  • 46
BorjaEst
  • 390
  • 2
  • 11
  • Why not to use `dict` directly? The `config` in the code behaves like a `dict` totally. – rustyhu Sep 30 '21 at 15:13
  • Flask uses a app.config which it is a dict. However, there is some not "flask" plugin which has its own config2. I want config2 to point to the value in config1 so I only have 1 config dict to worry about. – BorjaEst Oct 01 '21 at 06:58
  • What you're trying to do should just not be done. Solve your problem a different way. I don't really understand what your real problem is from your description, so I'm afraid I can't offer any suggestions - but doing some black magic with global variables, even if it were possible, is morally wrong and you might be punished in the afterlife for it. – kaya3 Oct 03 '21 at 17:33
  • 1
    This reads like you essentially want to implement pointers in Python which is discussed [here](https://stackoverflow.com/questions/3106689/pointers-in-python) – Robin Gertenbach Oct 03 '21 at 19:05
  • It is perfectly fine to know that it is just not possible. I will answer my own question then with your comment info. @kaya3 thanks for the eafterlife advice. – BorjaEst Oct 04 '21 at 06:29

1 Answers1

0

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?

BorjaEst
  • 390
  • 2
  • 11