__init__.py, __path__ and packaging

  • Thread starter Sandro Dentella
  • Start date
S

Sandro Dentella

Hi everybody,

I'm trying to fix the packaging of a very simple package, but some problem
show me that I have not well understood the whole mechanism

The structure of my package (some debug functions) is as follows:

python/
`-- dbg/
|-- __init__.py
`-- lib
|-- __init__.py
|-- debug.py
`-- gtk_dbg.py


my sys.path includes 'python' and I wanted that the content of debug.py was
simply included by: 'import dbg', so I wrote dbg/__init__.py as follows:

import os
Dir = os.path.dirname(__file__)
__path__ = [os.path.join(Dir, 'lib')]
from debug import *

It seems to work:

python$ python -c 'import dbg; print dir(dbg)'
['DBG', 'Dir', '__builtins__', '__doc__', '__file__', '__name__', \
'__path__', 'caller', 'debug', 'dshow', 'os', 're', 'show_caller', \
'sql_debug', 'sys']

BUT, if I set some variables they are not correctly seen:

import dbg
dbg.DBG = 1


function test included in debug.py raises NameError:

def test():
print DBG

NameError: global name 'DBG' is not defined`

What's happening? DBG seems to be set, as shown by dir(dbg)... any hints?
I'd also accept a hint for a different approch, if it's the case, but I'd
really would also understant this issue

Thanks in advance
sandro
*:)
 
S

Scott David Daniels

Sandro said:
The structure of my package:

python/
`-- dbg/
|-- __init__.py
`-- lib
|-- __init__.py
|-- debug.py
`-- gtk_dbg.py

my sys.path includes 'python' and I wanted that the content of debug.py was
simply included by: 'import dbg', so I wrote dbg/__init__.py as follows:

import os
Dir = os.path.dirname(__file__)
__path__ = [os.path.join(Dir, 'lib')]
from debug import *

What you probably want in python/dbg/__init__.py to get values is:

from dbg.lib.debug import *
BUT, if I set some variables they are not correctly seen:
import dbg
dbg.DBG = 1
function test included in debug.py raises NameError:
def test():
print DBG
NameError: global name 'DBG' is not defined`

What's happening? DBG seems to be set, as shown by dir(dbg)... any hints?
You misunderstand modules and python variables. Each module has a
dictionary associating the names of its globals and their current
values. After:
import dbg.lib.debug, dbg.lib.gtk_dbg
you have four modules:
dbg # Corresponds to python/dbg/__init__.py
dbg.lib # Corresponds to python/dbg/lib/__init__.py
dbg.lib.debug # Corresponds to python/dbg/lib/debug.py
dbg.lib.gtk_dbg # Corresponds to python/dbg/lib/gtk_dbg.py
Each has its own globals.
after:
dbg.DBG = 1
the dbg module's global dictionary contains an entry mapping 'DBG' to 1
after:
dbg.DBG = 1+2
the dbg module's global dictionary contains an entry mapping 'DBG' to 3

In no case will an assignment to a global in dbg cause an assignment to
anything in dbg.lib.debug. The "from dbg.lib.debug import *" statement
can be seen as a module import followed by a fancy multiple assignment,
where module dbg.lib.debug is first imported, then its globals are
assigned to globals of the same names in module dbg.

--Scott David Daniels
(e-mail address removed)
 
S

Sandro Dentella

In comp.lang.python, hai scritto:
Sandro said:
The structure of my package:

python/
`-- dbg/
|-- __init__.py
`-- lib
|-- __init__.py
|-- debug.py
`-- gtk_dbg.py

my sys.path includes 'python' and I wanted that the content of debug.py was
simply included by: 'import dbg', so I wrote dbg/__init__.py as follows:

import os
Dir = os.path.dirname(__file__)
__path__ = [os.path.join(Dir, 'lib')]
from debug import *

What you probably want in python/dbg/__init__.py to get values is:

from dbg.lib.debug import *

This does not work:

Traceback (most recent call last):
File "<string>", line 1, in ?
File "dbg/__init__.py", line 8, in ?
from dbg.lib.debug import *
ImportError: No module named lib.debug


You misunderstand modules and python variables. Each module has a
dictionary associating the names of its globals and their current
values. After:
import dbg.lib.debug, dbg.lib.gtk_dbg
you have four modules:
dbg # Corresponds to python/dbg/__init__.py
dbg.lib # Corresponds to python/dbg/lib/__init__.py
dbg.lib.debug # Corresponds to python/dbg/lib/debug.py
dbg.lib.gtk_dbg # Corresponds to python/dbg/lib/gtk_dbg.py
Each has its own globals.
after:
dbg.DBG = 1
the dbg module's global dictionary contains an entry mapping 'DBG' to 1
after:
dbg.DBG = 1+2
the dbg module's global dictionary contains an entry mapping 'DBG' to 3

In no case will an assignment to a global in dbg cause an assignment to
anything in dbg.lib.debug. The "from dbg.lib.debug import *" statement
can be seen as a module import followed by a fancy multiple assignment,
where module dbg.lib.debug is first imported, then its globals are
assigned to globals of the same names in module dbg.

This confirms to me that I'm seriously confused... so I started with a very
simple setup:
$ cat dbg.py
DBG = 1
def test():
global DBG
print DBG

def set():
global DBG
DBG = 3


$ cat m.py
from dbg import *

test()
#dbg.DBG = 2 ## does not work, no way to assign in module dbg
set() # this acts in dbg module and sets 'DBG = 3'
test() # test the value of DBG
print DBG


$ python m.py
1
3 # changed by 'set' that was 'imported'
1 # value of local DBG

isn't this contraddicting you words:
can be seen as a module import followed by a fancy multiple assignment,
where module dbg.lib.debug is first imported, then its globals are
assigned to globals of the same names in module dbg.

So: which is the way I can change a value of a package 'imported', only with
a function that sets it? is there a way to assign the value directly?
is there any way to make some introspection of what is really there (in
dbg)?

Thanks angain for any possible hint.

sandro
*:)
 
D

Dennis Lee Bieber

This confirms to me that I'm seriously confused... so I started with a very
simple setup:
$ cat dbg.py
DBG = 1
def test():
global DBG
print DBG

def set():
global DBG
DBG = 3


$ cat m.py
from dbg import *

test()
#dbg.DBG = 2 ## does not work, no way to assign in module dbg
set() # this acts in dbg module and sets 'DBG = 3'
test() # test the value of DBG
print DBG


$ python m.py
1
3 # changed by 'set' that was 'imported'
1 # value of local DBG


So: which is the way I can change a value of a package 'imported', only with
a function that sets it? is there a way to assign the value directly?
is there any way to make some introspection of what is really there (in
dbg)?
DO NOT USE

from module import *

Then... Qualify all module access with the module name.

dbg.py
-=-=-=-=-=-=-=-=-

DBG = 1

def test():
global DBG
print DBG

def set():
global DBG
DBG = DBG + 3

(main.py)
-=-=-=-=-=-=-=-=-

import dbg

dbg.test()
dbg.DBG = 10
dbg.test()
dbg.set()
dbg.test()

print dbg.DBG


output
-=-=-=-=-=-=-=-=-
1
10
13
13


Using "from <> import *" duplicates the "public" (top-level) names
of the imported module, making them local name in the importing module.
But you have to remember -- in Python, an assignment does not change
what the name is bound to; it binds the name to the new object. {In
other words, unlike classical language where "x = y" puts a copy of "y"
into the place allocated for "x" -- Python, instead puts the name "x"
onto the same /object/ that the name "y" is connected to... So the only
way to change something inside a module is to... change it inside the
module... using "module.name = newvalue" changes it inside "module"}

Now, why you couldn't do "dbg.DBG = ..."? Very simple... "from
module import *" doesn't give you a dbg /module/, it only gives you
references to each piece inside the module.
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
S

Sandro Dentella

Now, why you couldn't do "dbg.DBG = ..."? Very simple... "from
module import *" doesn't give you a dbg /module/, it only gives you
references to each piece inside the module.

really the reason why I wanted that should probably be solved in other
ways. I just wanted to split my dbg module in different files but load the
dbg module in one single operation:

dbg/
|-- __init__.py
|-- lib
|-- __init__.py
|-- debug.py
|-- gtk_dbg.py

and inside dbg/__init__.py I used "from dbg.debug import *" so that a single
'import dbg' could present me the module 'debug' (of course in this simple
case seems easier to put debug.py directly under dbg, but my main case is
a much more complex module, with a tree structure that reflects the
relation between modules that I want to hide to the end user).

But to summarize, if I use 'from my_module import *' there is no way to reach
directly 'my_module' and set a variable there?

Thanks again
sandro
*:)
I'm trying to fix the packaging of a very simple package, but some problem
show me that I have not well understood

the structure of my package (some debug functions) is as follows:

python/
`-- dbg/
|-- __init__.py
`-- lib
|-- __init__.py
|-- debug.py
`-- gtk_dbg.py


my sys.path includes 'python' and I wanted that the content of debug.py was
simply included by: 'import dbg', so I wrote dbg/__init__.py as follows:

import os
Dir = os.path.dirname(__file__)
__path__ = [os.path.join(Dir, 'lib')]
from debug import *
 
D

Dennis Lee Bieber

But to summarize, if I use 'from my_module import *' there is no way to reach
directly 'my_module' and set a variable there?
For the most part, the only good (IMHO) usage of "from <> import *"
to get /readonly/ access to a large a great number of names without
using the module name. Things like all the "constants" used to define
GUI parameters, say...

To change something that is within a module you have to have the
module as a container of names: "import <>" creates that container.
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top