Binding python variable to specific expression
I am developing a simple application that contains a Constants.py file containing all the configuration as it looks like
x = y
during program execution the y value changes, I want the xo value to update automatically as well, this can be specified as a binding, how can I achieve this
a source to share
Python variable names indicate the value. x=y
tells Python that the variable name x
should point to the value it currently points to y
.
When you change y
, the variable name y
points to the new value, and the variable name x
still points to the old value.
You cannot achieve what you want with simple variable names.
I like KennyTM's proposal for defining x
as a function, as it makes it explicit that the value x
requires some code to run (lookup for the y value).
However, if you want to maintain a consistent syntax (making all constants available the same way), you can use a class with properties (attributes that 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
This is where you change the "constant" y:
const.y='bar'
And the "constant" x also changes:
print(const.x)
# bar
You can also change x
,
const.x='foo'
and y
also changes:
print(const.y)
# foo
a source to share
If you change the value (object), 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 give a name to some other object, then the other names will refer to whatever they referred to before:
>>> a = 15
>>> print b
['foo']
How does python. Names are just references to objects. You can make a name reference to the same object referenced by another name, but you cannot assign a name reference to a different name. Attributing a name using the =
( a = 15
) operator changes the referenced value a
, so it cannot affect other names.
a source to share
There is a simple solution you can make. Just define the property and set the value fget
you defined.
For instance:
a = 7
@property
def b():
return a
if you ask for b you get something like this <property object at 0x1150418>
, but if you do b.fget()
you get 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 that way, otherwise I think you need to.
a source to share