Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Python Global Constant

Reply
Thread Tools

Python Global Constant

 
 
Krisztian Kepes
Guest
Posts: n/a
 
      07-09-2003
Hi !

I want to create an module and I want to use some Global Constant in it.
How to I create an global constant in module what is accessable in from other modules ?

like this example:

*** module dirs ***
const Const_Up=1
const Const_Down=1

*** module any ***
import dirs;
def CheckDir(Dir):
if Dir=dirs.Const_Up: xxx

?????

Thx:
Chris






 
Reply With Quote
 
 
 
 
Peter Hansen
Guest
Posts: n/a
 
      07-09-2003
Krisztian Kepes wrote:
>
> I want to create an module and I want to use some Global Constant in it.
> How to I create an global constant in module what is accessable in from other modules ?
>
> like this example:
>
> *** module dirs ***
> const Const_Up=1
> const Const_Down=1


Just do what you did above, without the "const" modifier, which
doesn't exist and is not really needed in Python.

> *** module any ***
> import dirs;
> def CheckDir(Dir):
> if Dir=dirs.Const_Up: xxx


This code should work fine, although you might want to follow
the Python conventions for capitalization and formatting of
your code, to make it more readable for others. For example,
variables and functions are generally mixed case, as in checkdir
or dir, while constants are usually ALLCAPS as in CONST_UP.

-Peter
 
Reply With Quote
 
 
 
 
Christoph Becker-Freyseng
Guest
Posts: n/a
 
      07-09-2003

>>*** module any ***
>>import dirs;
>>def CheckDir(Dir):
>> if Dir=dirs.Const_Up: xxx

>
>
> This code should work fine, although you might want to follow
> the Python conventions ........


What about using __builtins__ wouldn't make this the constant really global?


cbf


 
Reply With Quote
 
Ulrich Petri
Guest
Posts: n/a
 
      07-09-2003
"Peter Hansen" <> schrieb im Newsbeitrag
news:...
> Krisztian Kepes wrote:
>
> > *** module any ***
> > import dirs;
> > def CheckDir(Dir):
> > if Dir=dirs.Const_Up: xxx

>
> This code should work fine, although you might want to follow
> the Python conventions for capitalization and formatting of
> your code, to make it more readable for others. For example,
> variables and functions are generally mixed case, as in checkdir
> or dir, while constants are usually ALLCAPS as in CONST_UP.


No it wont. "if Dir = dirs.Const_Up:" is invalid syntax (Note the = instead
of ==)

Ciao Ulrich


 
Reply With Quote
 
Peter Hansen
Guest
Posts: n/a
 
      07-09-2003
Christoph Becker-Freyseng wrote:
>
> >>*** module any ***
> >>import dirs;
> >>def CheckDir(Dir):
> >> if Dir=dirs.Const_Up: xxx

> >
> >
> > This code should work fine, although you might want to follow
> > the Python conventions ........

>
> What about using __builtins__ wouldn't make this the constant really global?


A module is already global, in the sense that if you do "import xxx"
you will get a reference to a singleton module object (generally from
xxx.py), which provides a nice clean namespace for a set of names such
as constants.

This makes it easy for someone reading the code to see where a constant
is defined, and it provides a necessary level of organization.

Putting something in __builtins__ is not only stylistically a bad
idea for most things, but it also hides the source of the name and
anyone reading the file will be at a loss to figure out where it
came from unless every reference to it is preceded by a big comment::

# WARNING! The author of this code chose the silly approach
# of storing a reference to this constant in the __builtins__
# namespace, which is why you can't find where it is defined.
# This reference was stored in the initialization code that
# is in init.py, and instead of just leaving the name there
# so you could call it "init.CONSTANT", it was slipped in
# through the back door to let the author save five keystrokes,
# at the expense of readability, but with this comment everything
# will be okay.
x = CONSTANT

How is that better than using the proper approach of storing constants
in a module, such as "constant.py"?

-Peter
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      07-09-2003

> What about using __builtins__ wouldn't make this the constant really

global?

Short respone: this is an implementation-detail-dependent hack that
Guido discourges and that Guido would be willing to break if there
were sufficient gain otherwise.

Longer answer: I once though of doing this too. However, the language
reference specifies module import as the means to make objects
globally accessible. I don't believe that the language reference
specifies the implementation details for the builtins namespace.
While currently
implemented as a user-writeble dict of the {} type, bound to the name
__builtins__, this could change.

Terry J. Reedy


 
Reply With Quote
 
Greg Ewing (using news.cis.dfn.de)
Guest
Posts: n/a
 
      07-10-2003
Peter Hansen wrote:
> Just do what you did above, without the "const" modifier, which
> doesn't exist and is not really needed in Python.


If you *really* insist on preventing anyone from changing
them, it is possible, with some hackery. Here's one way
that works:

################################################## #####
#
# MyModule.py
#

_constants = ['PI', 'FortyTwo']

PI = 3.1415
FortyTwo = 42

import types

class _ConstModule(types.ModuleType):

__slots__ = []

def __setattr__(self, name, value):
if name in self.__dict__['_constants']:
raise ValueError("%s is read-only" % name)
self.__dict__[name] = value

del types
import MyModule
MyModule.__class__ = _ConstModule

################################################## #####

Figuring out *how* it works is left as an exercise
for the student.

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

 
Reply With Quote
 
Jp Calderone
Guest
Posts: n/a
 
      07-10-2003
On Thu, Jul 10, 2003 at 04:06:55PM +1200, Greg Ewing (using news.cis.dfn.de) wrote:
> Peter Hansen wrote:
> >Just do what you did above, without the "const" modifier, which
> >doesn't exist and is not really needed in Python.

>
> If you *really* insist on preventing anyone from changing
> them, it is possible, with some hackery. Here's one way
> that works:
>
> ################################################## #####
> #
> # MyModule.py
> #
>
> _constants = ['PI', 'FortyTwo']
>
> PI = 3.1415
> FortyTwo = 42
>
> import types
>
> class _ConstModule(types.ModuleType):
>
> __slots__ = []
>
> def __setattr__(self, name, value):
> if name in self.__dict__['_constants']:
> raise ValueError("%s is read-only" % name)
> self.__dict__[name] = value
>
> del types
> import MyModule
> MyModule.__class__ = _ConstModule
>


>>> import MyModule
>>> del MyModule._constants[:]
>>> MyModule.PI = 'Cherry, please'
>>> MyModule.PI

'Cherry, please'

Jp

--
"The problem is, of course, that not only is economics bankrupt but it has
always been nothing more than politics in disguise ... economics is a form
of brain damage." -- Hazel Henderson

 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      07-11-2003
On Thu, 10 Jul 2003 02:01:47 -0400, Jp Calderone <> wrote:

>On Thu, Jul 10, 2003 at 04:06:55PM +1200, Greg Ewing (using news.cis.dfn.de) wrote:
>> Peter Hansen wrote:
>> >Just do what you did above, without the "const" modifier, which
>> >doesn't exist and is not really needed in Python.

>>
>> If you *really* insist on preventing anyone from changing
>> them, it is possible, with some hackery. Here's one way
>> that works:
>>
>> ################################################## #####
>> #
>> # MyModule.py
>> #
>>
>> _constants = ['PI', 'FortyTwo']
>>
>> PI = 3.1415
>> FortyTwo = 42
>>
>> import types
>>
>> class _ConstModule(types.ModuleType):
>>
>> __slots__ = []
>>
>> def __setattr__(self, name, value):
>> if name in self.__dict__['_constants']:
>> raise ValueError("%s is read-only" % name)
>> self.__dict__[name] = value
>>
>> del types
>> import MyModule
>> MyModule.__class__ = _ConstModule
>>

>
> >>> import MyModule
> >>> del MyModule._constants[:]
> >>> MyModule.PI = 'Cherry, please'
> >>> MyModule.PI

> 'Cherry, please'
>
> Jp
>

Ok, this one is a little more resistant, I think (though I'm not sure how much more :
====< makeconst.py >================================================= ============
import os, sys
def makeconst(m):
modulename = m.__name__
mpath = m.__file__
sfront = [
'def forclosure(m):',
' dictinclosure = {'
]
sback = [
' }',
' class %s(object):'% modulename,
' def __getattribute__(self, name):',
' if name=="__dict__": return dictinclosure.copy()', # no mods
' return dictinclosure[name]',
' def __setattr__(self,name,val):',
' raise TypeError, "module %s is read-only"'%modulename,
' return vars()["%s"]()'%modulename,
''
]
if mpath.endswith('.pyc'): mpath = mpath[:-1]
if not mpath.endswith('.py'):
raise ValueError, 'Not .py or .pyc based module: %s of %r'%(modulename, mpath)
for line in file(mpath):
line = line.strip()
if not line or line[0]=='#' or not line[0].isupper(): continue
lh,rh = map(str.strip, line.split('=',1))
sfront.append(
' %r:m.%s,'% (lh,lh) # get actual bindings from pre-constified module
)
exec '\n'.join(sfront+sback)
constmod = vars()['forclosure'](m)
sys.modules[modulename] = constmod
return constmod

def importconst(name): return makeconst(__import__(name))
================================================== ===============================

and we'll import and "make constant" the module:

====< MyConsts.py >====================================
################################################## #####
#
# MyConsts.py
#

PI = 3.1415
FortyTwo = 42
================================================== =====
>>> import makeconst
>>> MyConsts = makeconst.importconst('MyConsts')
>>> MyConsts.PI

3.1415000000000002
>>> dir(MyConsts)

['FortyTwo', 'PI']
>>> MyConsts.FortyTwo

42
>>> MyConsts.FortyTwo = 43

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 11, in __setattr__
TypeError: module MyConsts is read-only
>>> setattr(MyConsts,'foo',123)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 11, in __setattr__
TypeError: module MyConsts is read-only
>>> MyConsts.__dict__

{'PI': 3.1415000000000002, 'FortyTwo': 42}
>>> MyConsts.__dict__['PI'] = 'Cherry?'
>>> MyConsts.__dict__

{'PI': 3.1415000000000002, 'FortyTwo': 42}
>>> vars(MyConsts)

{'PI': 3.1415000000000002, 'FortyTwo': 42}
>>> MyConsts.PI

3.1415000000000002


>>> object.__getattribute__(MyConsts,'__dict__')

{}
>>> object.__getattribute__(MyConsts,'__class__')

<class 'makeconst.MyConsts'>
>>> object.__getattribute__(MyConsts,'__class__').__di ct__

<dict-proxy object at 0x007DD6F0>
>>> object.__getattribute__(MyConsts,'__class__').__di ct__.keys()

['__module__', '__dict__', '__getattribute__', '__weakref__', '__setattr__', '__doc__']
>>> object.__getattribute__(MyConsts,'PI')

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'MyConsts' object has no attribute 'PI'

Well, we can force one that will come back that way
>>> object.__setattr__(MyConsts,'PI','Cherry ')


Not this way:
>>> MyConsts.PI

3.1415000000000002

But this way:
>>> object.__getattribute__(MyConsts,'PI')

'Cherry '

We can see it in the instance dict that was created:
>>> object.__getattribute__(MyConsts,'__dict__')

{'PI': 'Cherry '}

But not via the object normally:
>>> dir(MyConsts)

['FortyTwo', 'PI']
>>> MyConsts.__dict__

{'PI': 3.1415000000000002, 'FortyTwo': 42}
>>> getattr(MyConsts,'__dict__')

{'PI': 3.1415000000000002, 'FortyTwo': 42}

So you can force the instance to get a __dict__ with whatever apparent attribute, but you
can't make it apparent via normal attribute access, so it wouldn't affect modules importing
and using MyConsts normally:

>>> MyConsts.PI

3.1415000000000002

Well, some you can flesh out the special attributes/methods, but you get the drift.
We could also use a metaclass to fake the name exactly (when __name__ is returned
and in __repr__ and __str__.

If you import MyConsts after makeconst does its thing, I'm not sure how to sabotage the result of
the expression MyConsts.PI for other modules that have imported it, short of rebinding methods.
Since the data is not in a class variable or class dict, I you'd have to go after the closure cell.
I can find that (I think that's it below, though I'd have to print id(dictinclosure) to be sure),
e.g.,

>>> object.__getattribute__(MyConsts,'__class__').__ge tattribute__.im_func.func_closure[0]

<cell at 0x007D8FB0: dict object at 0x007DD5E0>

but how do you get at the dict in the cell? I don't guess it should be allowed, even if it's possible.

Otherwise you'll just have to mess with sys.modules similarly to get around it, I think, or accept
that you just have constant bindings (maybe to mutable objects though

Regards,
Bengt Richter
 
Reply With Quote
 
Christoph Becker-Freyseng
Guest
Posts: n/a
 
      07-12-2003
Hello,

Maybe I missunderstood the OP. So I said that __builtins__ might be
useful. I know that you should not use it in most cases because it makes
code less readable (where is xy defined?) and might cause unwanted
side-effects.
However e.g. if you're programming a big framework like Zope it is useful.

cbf




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 1 10-25-2006 06:50 PM
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 0 10-25-2006 01:04 PM
Understanding How To Use #ifdef Constant #define Constant Sequence In Multible Files Christopher M. Lusardi C++ 1 09-02-2004 07:43 AM
RE: Python Global Constant Michael Chermside Python 0 07-09-2003 12:48 PM
Re: Python Global Constant Jp Calderone Python 0 07-09-2003 09:21 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57