Question about a single underscore.

S

Steven W. Orr

I saw this and tried to use it:

------------------><8------------------- const.py-------------
class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value

import sys
sys.modules[__name__]=_const()
------------------><8------------------- const.py-------------

Then when I go to try to use it I'm supposed to say:

const.pi = 3.14159
const.e = 2.7178


Two questions:

1. Why do I not have to say

_const.pi = 3.14159
_const.e = 2.7178

and is this in the tutorial?

2. Can I make this behave in such a way that I can create my constants
with a classname that is different for different uses? e.g.,

irrational_const.pi = 3.14159
irrational_const.e = 2.7178

even_const.first = 2
even_const.firstPlus = 4

TIA

--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
 
P

Paul Rubin

Steven W. Orr said:
------------------><8------------------- const.py-------------
...
sys.modules[__name__]=_const()

__name__ is 'const' since this file is const.py. So you've
juset set the const module to actually be a const instance.
1. Why do I not have to say
_const.pi = 3.14159

const.pi refers to item 'pi' in the const module, which you've
set in sys.modules above.
2. Can I make this behave in such a way that I can create my constants
with a classname that is different for different uses? e.g.,
irrational_const.pi = 3.14159

Yes, irrational_const = _const()
 
B

Bart Ogryczak

I saw this and tried to use it:

------------------><8------------------- const.py------------- [...]
sys.modules[__name__]=_const()

__name__ == 'const', so you´re actually doing
const = _const()
 
S

Steven W. Orr

On Thursday, Feb 1st 2007 at 09:25 -0800, quoth Bart Ogryczak:

=>> I saw this and tried to use it:
=>>
=>> ------------------><8------------------- const.py-------------
=>[...]
=>> sys.modules[__name__]=_const()
=>
=>__name__ == 'const', so you´re actually doing
=>const = _const()

So how can I say this in const.py?

class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value

def __init__(self):
sys.modules[self]=_const()

import sys

to cause a different instantiation a la

foo = _const()

The goal would be to create different instances of consts.

I did try the previous suggestion

irrational_consts = _const()

but I got
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name '_const' is not defined
*>>> iii=const()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: _const instance has no __call__ method

------------
For ref:

class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value

import sys
sys.modules[__name__]=_const()



--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
 
P

Paul Rubin

Steven W. Orr said:
to cause a different instantiation a la
foo = _const()
The goal would be to create different instances of consts.

The idea of putting it in sys.modules is so it's visible in all modules.

You need
iii = const._const
 
S

Steven W. Orr

On Thursday, Feb 1st 2007 at 10:36 -0800, quoth Paul Rubin:

=>> to cause a different instantiation a la
=>> foo = _const()
=>> The goal would be to create different instances of consts.
=>
=>The idea of putting it in sys.modules is so it's visible in all modules.
=>
=>> >>> import const
=>> >>> iii=_const()
=>
=>You need
=> iii = const._const
=>--
=>http://mail.python.org/mailman/listinfo/python-list
=>


547 > python
Python 2.3.5 (#2, May 4 2005, 08:51:39)
[GCC 3.3.5 (Debian 1:3.3.5-12)] on linux2
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: _const instance has no attribute '_const'
*>>> iii = const._const()
Traceback (most recent call last):


What am I missing here? (Sorry if it should be obvious)

--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
 
P

Paul Rubin

Steven W. Orr said:
AttributeError: _const instance has no attribute '_const'
What am I missing here? (Sorry if it should be obvious)

Oh I see. No it's not obvious. module "const" has gotten overwritten
by the _const instance. I think that module author was too clever for
his or her own good.
 
B

Bruno Desthuilliers

Paul Rubin a écrit :
Oh I see. No it's not obvious. module "const" has gotten overwritten
by the _const instance. I think that module author was too clever for
his or her own good.

Not necessarily - given the intent, it's just smart IMHO. But the
workaround is quite obvious anyway:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "const.py", line 5, in __setattr__
raise self.ConstError, "Can't rebind const(%s)"%name
const.ConstError: Can't rebind const(pi)
HTH
 
B

Bruno Desthuilliers

Steven W. Orr a écrit :
I saw this and tried to use it:

------------------><8------------------- const.py-------------
class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value

import sys
sys.modules[__name__]=_const()
------------------><8------------------- const.py-------------

Then when I go to try to use it I'm supposed to say:

const.pi = 3.14159
const.e = 2.7178


Two questions:

1. Why do I not have to say

_const.pi = 3.14159
_const.e = 2.7178

Because of the last two lines of module const. sys.modules is a dict of
already imported modules (yes, Python's modules are objects too), which
avoids modules being imported twice or more. __name__ is a magic
variable that is set either to the name of the module - when it's
imported - or to '__main__' - when it's being directly executed as the
main program. Here, when you first do 'import const', the module's code
itself sets sys.modules['const'] to an instance of _const, so what you
import in your namespace as 'const' is not the const module instance but
a _const instance.
and is this in the tutorial?

Hmmm... Not sure. FWIW, it's mostly a hack !-)
2. Can I make this behave in such a way that I can create my constants
with a classname
s/classname/name/

that is different for different uses? e.g.,

irrational_const.pi = 3.14159
irrational_const.e = 2.7178

even_const.first = 2
even_const.firstPlus = 4

irrational_const = const.__class__()
even_const = const.__class__()

Now while I find this hack interesting, it's also totally unpythonic
IMHO. The usual convention is to use ALL_UPPER names for (pseudo)
symbolic constants, and I don't see any reason to forcefit B&D languages
concepts into Python.

My 2 cents...
 
S

Steven W. Orr

On Thursday, Feb 1st 2007 at 21:45 +0100, quoth Bruno Desthuilliers:

=>Steven W. Orr a écrit :
=>> I saw this and tried to use it:
=>>
=>> ------------------><8------------------- const.py-------------
=>> class _const:
=>> class ConstError(TypeError): pass
=>> def __setattr__(self,name,value):
=>> if self.__dict__.has_key(name):
=>> raise self.ConstError, "Can't rebind const(%s)"%name
=>> self.__dict__[name]=value
=>>
=>> import sys
=>> sys.modules[__name__]=_const()
=>> ------------------><8------------------- const.py-------------
=>>
=>> Then when I go to try to use it I'm supposed to say:
=>>
=>> const.pi = 3.14159
=>> const.e = 2.7178
=>>
=>>
=>> Two questions:
=>>
=>> 1. Why do I not have to say
=>>
=>> _const.pi = 3.14159
=>> _const.e = 2.7178
=>
=>Because of the last two lines of module const. sys.modules is a dict of
=>already imported modules (yes, Python's modules are objects too), which
=>avoids modules being imported twice or more. __name__ is a magic
=>variable that is set either to the name of the module - when it's
=>imported - or to '__main__' - when it's being directly executed as the
=>main program. Here, when you first do 'import const', the module's code
=>itself sets sys.modules['const'] to an instance of _const, so what you
=>import in your namespace as 'const' is not the const module instance but
=>a _const instance.
=>
=>> and is this in the tutorial?
=>
=>Hmmm... Not sure. FWIW, it's mostly a hack !-)
=>
=>> 2. Can I make this behave in such a way that I can create my constants
=>> with a classname
=>
=>s/classname/name/
=>
=>> that is different for different uses? e.g.,
=>>
=>> irrational_const.pi = 3.14159
=>> irrational_const.e = 2.7178
=>>
=>> even_const.first = 2
=>> even_const.firstPlus = 4
=>
=>irrational_const = const.__class__()
=>even_const = const.__class__()
=>
=>Now while I find this hack interesting, it's also totally unpythonic
=>IMHO. The usual convention is to use ALL_UPPER names for (pseudo)
=>symbolic constants, and I don't see any reason to forcefit B&D languages
=>concepts into Python.

Ok. Now *maybe* we're getting to where I want to be. My const.py now looks
like this:

class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value

import sys
sys.modules[__name__]=_const()

and in a seperate module call key_func_consts I say:

import const
# Define constants for Key Function Field.
KeyFuncConst = const.__class__()
KeyFuncConst.NotDefined = 0x00

And in my main module I have
#! /usr/bin/python
import const
import key_func_consts
print KeyFuncConst.MSK


but the last print fails with

The goal is to be able to create classes of global constants.

561 > t_const.py
Traceback (most recent call last):
File "./t_const.py", line 6, in ?
print KeyFuncConst.MSK
NameError: name 'KeyFuncConst' is not defined

Do I need to get the KeyFuncConst object into sys.modules somehow? I know
I'm close.

--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
 
B

Bruno Desthuilliers

Steven W. Orr a écrit :
On Thursday, Feb 1st 2007 at 21:45 +0100, quoth Bruno Desthuilliers:
(snip)

=>irrational_const = const.__class__()
=>even_const = const.__class__()
=>
=>Now while I find this hack interesting, it's also totally unpythonic
=>IMHO. The usual convention is to use ALL_UPPER names for (pseudo)
=>symbolic constants, and I don't see any reason to forcefit B&D languages
=>concepts into Python.

Ok. Now *maybe* we're getting to where I want to be. My const.py now looks
like this:

class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value

import sys
sys.modules[__name__]=_const()

and in a seperate module call key_func_consts I say:

import const
# Define constants for Key Function Field.
KeyFuncConst = const.__class__()
KeyFuncConst.NotDefined = 0x00

And in my main module I have
#! /usr/bin/python
import const

Note that you don't need it if you don't use it directly.
import key_func_consts
print KeyFuncConst.MSK


but the last print fails with

A NameError, of course. key_func_consts is the module, KeyFuncConst is
an attribute of this module. You either need to

1/ use a fully qualified name:

import key_func_consts
print key_func_consts.KeyFuncConst.MSK

or
2/ import the KeyFuncConst name directly:

from key_func_consts import KeyFuncConst
print KeyFuncConst.MSK

or
3/ use the same dirty hack as in the const module - but this is starting
to be very ugly and unpythonic, so I won't give an implementation
example !-)

Also, note that since you did not define KeyFuncConst.MSK in the
key_func_const module, you'll then have an AttributeError !-)
The goal is to be able to create classes of global constants.

Then just define your "constants" in the module and import it:

# key_func_const.py
NOT_DEFINED = 0x00
MSK = 42

# main.py
import key_func_const
print key_func_const.NOT_DEFINED
print key_func_const.MSK

Do I need to get the KeyFuncConst object into sys.modules somehow? I know
I'm close.

Nope. You're going the wrong direction. It's a typical case of arbitrary
overcomplexification. Please re-read the last paragraph of my previous
post. By convention, in Python, ALL_UPPER names means "constant value,
dont touch". The example I give you above is the Pythonic way of doing
things, it's dead simple, and *it just works* - so why bother messing
with sys.modules hacks ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top