initialization in python

K

koranthala

How does an average product handle initialization in python?
I am facing lot of issues in handling initialization, especially if I
import specific variables, due to the variables not getting updated.

For example - taking a sqlalchemy based product:
Module database:
^^^^^^^^^^^^^^^^^^^
Session = None

def init(dbname):
engine = create_engine('sqlite:///%s' %dbname)
...
global Session
Session = sessionmaker(bind=engine)

In entry module to the application (APPENTRY):
^^^^^^^^^^^^^^^^^^^
import A, B, C, D <---- Please note, very important
.....
.....
database.init('testdb.db')

Now in user module A:
^^^^^^^^^^^^^^^^^^^^^^^^^^
from database import Session
print Session
--->This will print None, because at APPENTRY, during importing A
itself, Session is stored.
I have to call database.Session to get the values.

Why is the variable not getting updated? Can anyone help me out?
 
J

John Machin

How does an average product handle initialization in python?
I am facing lot of issues in handling initialization, especially if I
import specific variables, due to the variables not getting updated.

For example - taking a sqlalchemy based product:
Module database:
^^^^^^^^^^^^^^^^^^^
Session = None

def init(dbname):
   engine = create_engine('sqlite:///%s' %dbname)
   ...
   global Session
   Session = sessionmaker(bind=engine)

In entry module to the application (APPENTRY):
^^^^^^^^^^^^^^^^^^^
import A, B, C, D  <---- Please note, very important
....
....
database.init('testdb.db')

Now in user module A:
^^^^^^^^^^^^^^^^^^^^^^^^^^
from database import Session
print Session
--->This will print None, because at APPENTRY, during importing A
itself, Session is stored.

This is happening when you import A, which happens *before* you call
database.init(). database.init binds the name database.Session to a
new value. The name A.Session has been bound earlier to the value
None.
I have to call database.Session to get the values.

I don't understand that sentence. Is database.Session callable (i.e.
is a function or class)? What valueS (plural)?
Why is the variable not getting updated?

Firstly, it's not a "variable" in the sense of a named slice of memory
to which various values can be assigned.

Secondly, it could be updated only if the "from database import
Session" operated like it was creating an alias e.g.
A.Session isanaliasof database.Session
like a C macro
#define A_Session database_Session
but it isn't; its effect is that of a fancy "assignment", more or less
like:
import database
Session = database.Session
del database

In any case, mucking about with module globals like you are trying to
do is not a good idea. As you have seen, it introduces dependencies
like you need to import A after the database is initiated. As soon as
you need more than one session at a time, or the single session needs
to be closed and restarted, it really falls apart. Try passing your
session around as a function arg, or as an attribute of an object that
contains current state information.

HTH,
John
 
K

koranthala

This is happening when you import A, which happens *before* you call
database.init(). database.init binds the name database.Session to a
new value. The name A.Session has been bound earlier to the value
None.


I don't understand that sentence. Is database.Session callable (i.e.
is a function or class)? What valueS (plural)?


Firstly, it's not a "variable" in the sense of a named slice of memory
to which various values can be assigned.

Secondly, it could be updated only if the "from database import
Session" operated like it was creating an alias e.g.
    A.Session isanaliasof database.Session
like a C macro
    #define A_Session database_Session
but it isn't; its effect is that of a fancy "assignment", more or less
like:
    import database
    Session = database.Session
    del database

In any case, mucking about with module globals like you are trying to
do is not a good idea. As you have seen, it introduces dependencies
like you need to import A after the database is initiated. As soon as
you need more than one session at a time, or the single session needs
to be closed and restarted, it really falls apart. Try passing your
session around as a function arg, or as an attribute of an object that
contains current state information.

HTH,
John
This is happening when you import A, which happens *before* you call
database.init(). database.init binds the name database.Session to a
new value. The name A.Session has been bound earlier to the value
None.

I guessed as much. But, I was under the impression that if the
original value is modified, the variables value also will change.
I don't understand that sentence. Is database.Session callable (i.e.
is a function or class)? What valueS (plural)?

Session() here is a session manager in SQLAlchemy. database.Session()
creates a new session.
import database
Session = database.Session
del database

Thank you. This answers my query.
In any case, mucking about with module globals like you are trying to
do is not a good idea. As you have seen, it introduces dependencies

I avoid global variables as much as possible. But SQLAlchemy tutorial
recommends this method of assignment. So, I was using this. Anyways, I
now use database.Session always, and these dependencies are no longer
there.
 
T

Terry Reedy

'Initializing' names is not necessary. Delete this. Without it, your
error would be more obvious.

This **rebinds* the module name 'Session' to a new object, making the
initial bindin irrelevant and misleading.

[snip]
I guessed as much. But, I was under the impression that if the
original value is modified, the variables value also will change.

Python has names and slots bound to objects. Some objects are mutable
and some not. None is not mutable. You replaced it.

If you had done something like

Session = sessionmaker()

def init(dbname):
Session.engine = create_engine('sqlite:///%s' %dbname)
...

then you would have *modified* the original object (value) bound to
'Session' and would have seen the behavior you expected.

Terry Jan Reedy
 
K

koranthala

'Initializing' names is not necessary.  Delete this.  Without it, your
error would be more obvious.

This **rebinds* the module name 'Session' to a new object, making the
initial bindin irrelevant and misleading.

[snip]


I guessed as much. But, I was under the impression that if the
original value is modified, the variables value also will change.

Python has names and slots bound to objects.  Some objects are mutable
and some not.  None is not mutable.  You replaced it.

If you had done something like

Session = sessionmaker()

def init(dbname):
     Session.engine = create_engine('sqlite:///%s' %dbname)
     ...

then you would have *modified* the original object (value) bound to
'Session' and would have seen the behavior you expected.

Terry Jan Reedy

I did not think about it. I was using database.Session till now.
I have now modified the code.
Thank you very much, Terry Jan Reedy
 

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

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,296
Latest member
HeikeHolli

Latest Threads

Top