30

I have a need to add module attributes at run time. For example, when a module is loaded, it reads the file where the data is contained. I would like that data to be available as a module attribute, but the data is only available at run time.

How can I add module attributes at run time?

7 Answers 7

49

Thanks @Dharmesh. That was what I needed. There is only one change that needs to be made. The module won't be importing itself so to get the module object I can do:

setattr(sys.modules[__name__], 'attr1', 'attr1')

Sign up to request clarification or add additional context in comments.

Comments

18

If you don't know the attribute name until runtime, use setattr:

>>> import mymodule
>>> setattr(mymodule, 'point', (1.0, 4.0))
>>> mymodule.point
(1.0, 4.0)

3 Comments

This is scarcely a good example! The module should be setting its own attribute, not the caller!!
@John Machin: In that case @Jeremy can do some module magic like the Werkzeug code: github.com/mitsuhiko/werkzeug/blob/master/werkzeug/__init__.py
Updated link for Werkzeug: github.com/pallets/werkzeug
4

Create dynamic class 'Module' and add attributes dynamically using dictionary like :

attributes = {'attr1': 'attr1', 'attr2': 'attr2'}
module = type('Module', (), attributes)

OR Create only dynamic class 'Module'

module = type('Module', (), {})

and add attribute with setattr method like this:

setattr(module, 'attr3', 'attr3')

OR

import module
setattr(module, 'attr1', 'attr1')

Comments

4

A module attribute is a variable in the module global scope.

if you want to set an attribute from the module itself 'at runtime' the correct way is

globals()['name'] = value

(Note: this approach only works for globals, not for locals.)

if you want to set an attribute from the scope where the module has been imported just set it:

import myModule
setattr(myModule, 'name', 10)

Complete example:

#m.py
def setGlobal(name, value):
    globals()[name] = value

--

#main.py
import m

m.setGlobal('foo', 10)
print(m.foo) #--> 10

#Moreover:

from m import foo
print(foo) #--> 10   (as Expected)

m.setGlobal('foo', 20)
print(m.foo) #--> 20  (also as expected)

#But:
print(foo) #--> 10

Comments

1

Just set it.

my_object = MyObject()
my_object.my_custom_attribute = 'my_value'

7 Comments

This works great if you know "my_custom_attribute", but I don't know what it is until run time.
You don't know the value, or the key? If it's the value, you can do the above at runtime just as well any other. If it's the key, just use setattr(my_object, my_key, 'my_value').
@Jeremy: How are importers of your module going to know the name of "my_custom_attribute"? In other words, how will they access its value?
@martineau Those who will be using my module will know what to expect based on the context. Of course, I will also provide information in the documentation for the module.
@Jeremy, @martineau: "know what to expect based on the context" smells rather iffy to me. Seems to need a lot of if/elif*/else code in each caller.
|
1

Add it as a key to the object's internal dictionary __dict__

my_object.__dict__['newattribute'] = 'attributevalue'

Comments

-7

The global scope of a module is the module itself, so just set a global.

# module.py
a = 1

# script.py
import module
print module.a
# 1

7 Comments

-1: The question was about adding an attribute at runtime. This doesn't answer that question.
@SlashV: This is done at runtime. When else do you think you would do this? (Congratulations on announcing an incorrect downvote.)
No need to be rude. Please explain where the runtime bit is. As in: module.py doesn't have "a" after being imported and "a" is added to module.py's dictionary afterwards i.e. 'during runtime'. That's how I understood "runtime" in this question. Feel free to explain if you think I misunderstood that.
Thanks for explaining to me how python works, but the original question explicitly states that the author doesn't know the name of the attribute at the time he is writing the module, so your response just doesn't answer the question. Period. You can talk as long as you like and discuss what runtime means and whatever, but at the end of the day you'll have to admit that you didn't answer the question and that my downvote was thus correct. You can "congratulate" me and say that I "proudly announce" things, which is all just rubbish to avoid facing the fact that you're just wrong here!
Though that is admittedly more trivial, your example also doesn't demonstrate setting the data of the attribute when that data is unknown at the time of writing of the module. (btw. all the off topic/ugly stuff in this conversation is yours)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.