Can Modules Have Properties the Same Way That Objects Can

Can modules have properties?

Python doesn't care that what's in sys.modules is actually a module. So you can just:

# game.py
class Game(object):
pass

import sys
sys.modules["game"] = Game()

Now other modules that import game will get the Game instance, not the original module.

I'm not sure I recommend it, but it'll do what you want.

properties on a module?

I guess its something to do with the function being defined on a
module, not an object...

Why not use an object then? :)

default_config.py

_DEFAULT_UNIT_ID = -1
_DEFAULT_UPLOAD_HOUR = 2
_MINUTES_PER_HOUR = 60

class BaseConfig(object):
def __init__(self, unit_id=_DEFAULT_UNIT_ID, upload_hour=_DEFAULT_UPLOAD_HOUR):
self.unit_id = unit_id
self.upload_hour = upload_hour

@property
def upload_minute(self):
return self.unit_id % _MINUTES_PER_HOUR

config.py

from default_config import BaseConfig

# organized place to put non-default parameters
config_dict = {
'unit_id': 12,
'upload_hour': 3,
}

CONFIG = BaseConfig(**config_dict)

some_file.py

from config import CONFIG

print CONFIG.upload_hour, CONFIG.upload_minute # "3 12"

I would also consider just combining default_config.py and config.py if there's no need to separate them, since it would be easier to see what keyword arguments the BaseConfig takes.

Can modules have properties?

Python doesn't care that what's in sys.modules is actually a module. So you can just:

# game.py
class Game(object):
pass

import sys
sys.modules["game"] = Game()

Now other modules that import game will get the Game instance, not the original module.

I'm not sure I recommend it, but it'll do what you want.

Requiring same module in different modules are referencing different objects

It was the character casing problem on require statement. I fixed the path with proper casing and it fixed...

Fixed

const { languageCountryCodesData } = require('../../data/frontEnd/languageCountryCodes');

To

const { languageCountryCodesData } = require('../../data/frontend/languageCountryCodes');

Changed 'frontEnd' to 'frontend'

How come I can modify the properties of a named return object inside of a module, but not modify the object itself?

However, I cannot do publicAPI = {} or set the publicAPI object itself, e.g., publicAPI = {a: 1}.

Yes, you can. It just has no effect at all on foo.

Why is this the case?

Because when you do:

return publicAPI;

what's returned is the value of publicAPI, not a reference to the variable. That value is the object reference. If you change the value that's in the publicAPI variable later, that has no effect on anything that has received the previous value of the variable.

Is there a way to modify the object itself?

Your example of assigning to the identify property changes the object (e.g., changes the state of one of the object's properties). But the only way to change which object foo refers to is to assign to foo. Nothing you do to publicAPI can change what object foo refers to.

Property functions out of class

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?

How to assign a __call__ method to a module/package?

Yes, you can do something like that.

foo_module.py

class Foo:
def __call__(self, arg):
print(f'Foo({arg!r}) called')

_ref, sys.modules[__name__] = sys.modules[__name__], Foo()


main.py

import foo_module

foo_module(123) # -> Foo(123) called


Related Topics



Leave a reply



Submit