tags:

views:

66

answers:

4

I am developing a simple application which hava a file Constants.py containing all configuration, it is like this

x = y

during execution of program , the value of y changes , I want value of x o get updated too , automatically, this can be reffered as binding, how can I achieve this

A: 

If you change the value (object) itself, then all references to it will be updated:

>>> a = []
>>> b = a  # b refers to the same object a is refering right now
>>> a.append('foo')
>>> print b
['foo']

However, if you make the name point to some other object, then other names will still reference whatever they were referencing before:

>>> a = 15
>>> print b
['foo']

That's how python works. Names are just references to objects. You can make a name reference the same object another name is referencing, but you can't make a name reference another name. Name attribution using the = operator (a = 15) changes what a refers to, so it can't affect other names.

nosklo
A: 

if your configuration values are inside a class, you could do something like this:

>>> class A(object):
...     a = 4
...     @property
...     def b(self):
...         return self.a
... 

then, every time you access b, it will return the value of a.

dedsm
A: 

In Python variable names point at values. x=y tells Python that the variable name x should point at the value that y is currently pointing at.

When you change y, then the variable name y points at a new value, while the variable name x still points at the old value.

You can not achieve what you want with plain variable names.

I like KennyTM's suggestion to define x as a function since it makes explicit that the value of x requires running some code (the lookup of the value of y).

However, if you want to maintain a uniform syntax (making all the constants accessible in the same way), then you could use a class with properties (attributes which call getter and setter functions):

Constants.py:

class BunchOConstants(object):
    def __init__(self, **kwds):
        self.__dict__.update(kwds)
    @property
    def x(self):
        return self.y
    @x.setter
    def x(self,val):
        self.y=val
const=BunchOConstants(y=10,z='foo')

Your script.py:

import Constants

const=Constants.const
print(const.y)
# 10
print(const.x)
# 10

Here you change the "constant" y:

const.y='bar'

And the "constant" x is changed too:

print(const.x)
# bar

You can change x also,

const.x='foo'

and y too gets changed:

print(const.y)
# foo
unutbu
A: 

There is a simple solution you can do. Just define a property and ask for the fget value you defined.

For example:

a = 7

@property 
def b():
    return a

if you ask for b, you will get something like this <property object at 0x1150418> but if you do b.fget(), you will obtain the value 7

Now try this:

a = 9
b.fget()  # this will give you 9. The current value of a

You don't need to have a class with this way, otherwise, I think you will need it.

Harph