473,395 Members | 1,458 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

I thought I'd 'got' globals but...

I thought I had 'got' globals but this one seems strange.
I want my example function 'doIt' to use and optionally modify a module
variable 'gname', so I declare 'global gname' in the function, but when
modified it doesn't stay modified.

gname = 'Sue'
def doIt(name = gname):
global gname
gname = name
print 'doIt name', name, 'gname', gname

print 'start gname', gname
doIt()
doIt(name='Lisa')
doIt()
print 'finish gname', gname

gives...
start gname Sue
doIt name Sue gname Sue
doIt name Lisa gname Lisa
doIt name Sue gname Sue
finish gname Sue

The variable gname has reverted back to value 'Sue'

Curiously though, without the third doIt() call, it works...
print 'start gname', gname
doIt()
doIt(name='Lisa')
#doIt()
print 'finish gname', gname

gives...
start gname Sue
doIt name Sue gname Sue
doIt name Lisa gname Lisa
finish gname Lisa

The variable gname has been modified to 'Lisa'

Any ideas how I can make the 'Lisa' assignment permanent forever in 2nd
doIt? Thanks

(Note. Contrived example substitutes for a web-type app, where, if the
page is called without arguments then it displays the global defaults.
If the page is called with form arguments then it should be able to
change the global defaults)

Jul 6 '06 #1
17 1255
meridian wrote:
I thought I had 'got' globals but this one seems strange.
I want my example function 'doIt' to use and optionally modify a module
variable 'gname', so I declare 'global gname' in the function, but when
modified it doesn't stay modified.

gname = 'Sue'
def doIt(name = gname):
This is a FAQ, cf:
http://www.python.org/doc/faq/genera...etween-objects

Briefly : default args are eval'd only once at load/import time.

Any ideas how I can make the 'Lisa' assignment permanent forever in 2nd
doIt? Thanks
def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name
(Note. Contrived example substitutes for a web-type app, where, if the
page is called without arguments then it displays the global defaults.
If the page is called with form arguments then it should be able to
change the global defaults)
Modifying globals from within a function is usually a very bad idea.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 6 '06 #2

Bruno Desthuilliers wrote:
def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name
Thanks Bruno, works a treat...

Jul 6 '06 #3
meridian wrote:
Bruno Desthuilliers wrote:
>>def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name


Thanks Bruno, works a treat...
But still very probably a bad idea.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 6 '06 #4

Bruno Desthuilliers wrote:
meridian wrote:
Bruno Desthuilliers wrote:
>def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name

Thanks Bruno, works a treat...
But still very probably a bad idea.
Ok, my curiosity is pique'd - is there a better way to hold my
app/module globals?
I must say I'd prefer not to write global <varin every function, for
every global var I need.
Maybe there's a simpler way to structure?... by a global class or
something?
Cheers
Steve

Jul 6 '06 #5

You mentioned earlier that
"Modifying globals from within a function is usually a very bad idea."

Most of my app consists of functions or class/object functions, that's
all I do in OOP.
Did you mean that modifying globals from anywhere is bad? or globals
are bad? or don't code using methods/functions? not sure...

Jul 6 '06 #6
meridian a écrit :
Bruno Desthuilliers wrote:
>>meridian wrote:
>>>Bruno Desthuilliers wrote:
def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name

Thanks Bruno, works a treat...

But still very probably a bad idea.

Ok, my curiosity is pique'd - is there a better way to hold my
app/module globals?
Probably !-)

Now which one depends on your app design and execution model...
I must say I'd prefer not to write global <varin every function, for
every global var I need.
Maybe there's a simpler way to structure?... by a global class or
something?
<ot>What is a "global class" ?</ot>

The problem with "app globals" is that they introduce too much coupling
(you end up having all your code depending on the globals). So the first
thing to do is identify who really needs to know what, and who is
responsible for knowing what. Anyway, most globals should be
configuration stuff - so usually read only. There are very good reasons
to avoid modifying globals in functions, and specially when it comes to
web programming where you have to handle concurrent access (which is why
I insist on telling you that what you want to do may be very dangerous).

Usually one uses a variant of the MVC, which helps separating concerns :
the model is about data (structure and persistance), the view(s) about
outputs (display data), and the controler about inputs (processing the
request). The flow is something like: controller parses request, takes
any appropriate action, selects appropriate elements from the model,
feed'em to appropriate view, and returns the result of view execution as
a response (general scheme, depends on whether it's plain cgi,
mod_python, fastcgi, wsgi, standalone server or whatnot).

It's clear that the controler needs some knowldge about the model and
the views, that the views are tightly coupled to the model but don't
need to know about the controller, and that the model just don't give a
damn about both controller and views. So we have:

controller -depends on model and view
view -depends on model
model -depends on nobody

Since handling a request is the controller's duty, the model should not
know about the request. The only 'global' things the model has to know
are related to data access configuration (db connection string, physical
path to resources on the filesystem etc...). Since the model is called
by the controller, it's the controller's job to pass these informations
to the model when appropriate.

Views may also need to access app-wide settings like urls to resources,
localisation stuff etc. Here again, since views are invoked by the
controller, it's usually the controller that is responsible for passing
relevant knowledge to the views - either directly (raw data) or
indirectly (thru some helper objects that holds the required knowledge
and are called by the view code).

As you can see, you've already eliminated any needs for globals in both
the views and the model (view or model specific module-level
pseudo-constants set aside, but then it's mostly safe).

I don't know which web solution you use, but I strongly suggest that you
take some time studying existing web applications or frameworks like
Trac, Django, CherryPy etc.

HTH
Jul 6 '06 #7
meridian a écrit :
You mentioned earlier that
"Modifying globals from within a function is usually a very bad idea."

Most of my app consists of functions or class/object functions, that's
all I do in OOP.
Did you mean that modifying globals from anywhere is bad?
Yes, definitively. Even without concurrent access, it very rapidly turns
the code into an unscrutable mess.
or globals
are bad?
Mostly, yes.

As usual, this is not a hard rule but a guideline. But I use as few
globals as possible, and almost all of them are read-only. The very few
exceptions are dirty hacks, mostly called at init time.
or don't code using methods/functions?
Err...
Jul 6 '06 #8
Thanks Bruno. Not only do you give solutions to my problem but also
throw in great MVC tutorials too.
You're a gent.

I'm using
controller -A CherryPy app
views -Cheetah Templating for the html & data
model -mostly SQLite DB using pysqlite
also Config

It's only a desk-web app for single-user, so no concurrency issues.
However, taking on board your advice to avoid globals, I've now
realised that the info that I need to retain between pages can simply
be session information (for the only user) that can be initialised at
startup from the config.
So I'm looking at just storing it all in the cherrypy.session ram vs
using python globals.
Thanks again & Regards
Steve

Jul 7 '06 #9
meridian wrote:
Thanks Bruno. Not only do you give solutions to my problem but also
throw in great MVC tutorials too.
You're a gent.
(blush)
I'm using
controller -A CherryPy app
views -Cheetah Templating for the html & data
model -mostly SQLite DB using pysqlite
also Config

It's only a desk-web app for single-user, so no concurrency issues.
Err... I would not be so confident wrt/ this point. What about having
two browser windows opened on different pages of the app ?
However, taking on board your advice to avoid globals, I've now
realised that the info that I need to retain between pages can simply
be session information (for the only user) that can be initialised at
startup from the config.
So I'm looking at just storing it all in the cherrypy.session ram vs
using python globals.
Think this will be better !-)

But still, avoid overusing sessions - ie, don't make session available
to objects just for covenience when you can pass required data as params.

My 2 cents...

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 7 '06 #10

Bruno Desthuilliers wrote:
>
def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name
Sorry for this very basic question, but I don't understand why I should
add the global into the function body before using it.
This function works even if I don't add the global.
Just to try this out, I wrote this variant:

gname = 'Luis'

def doIt2(name=None):
if name is None:
name = gname
return name

print doIt2() --returns Luis.

So, what's the point of writing the function this way instead?

def doIt2(name=None):
global gname
if name is None:
name = gname
return name
luis

Jul 7 '06 #11
try this:

gname = 'nate'
def test():
gname = 'amy'
print gname

test()
print gname

outputs:
'amy'
'nate'

whereas this:
gname = 'nate'
def test():
global gname
gname = 'amy'
print gname

test()
print gname

outputs:
'amy'
'amy'

Luis M. González wrote:
Bruno Desthuilliers wrote:

def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name

Sorry for this very basic question, but I don't understand why I should
add the global into the function body before using it.
This function works even if I don't add the global.
Just to try this out, I wrote this variant:

gname = 'Luis'

def doIt2(name=None):
if name is None:
name = gname
return name

print doIt2() --returns Luis.

So, what's the point of writing the function this way instead?

def doIt2(name=None):
global gname
if name is None:
name = gname
return name
luis
Jul 7 '06 #12

nate wrote:
try this:

gname = 'nate'
def test():
gname = 'amy'
print gname

test()
print gname

outputs:
'amy'
'nate'

whereas this:
gname = 'nate'
def test():
global gname
gname = 'amy'
print gname

test()
print gname

outputs:
'amy'
'amy'
OK, so I should include the global only if I plan to modify it.
Otherwise, I don't need to include it. Am I right?

Jul 7 '06 #13
OK, so I should include the global only if I plan to modify it.
Otherwise, I don't need to include it. Am I right?
I guess you could say that's true. I'm hardly an expert so I couldn't
say there aren't other potential ramifications. (anyone?)

But, as a rule I would declare the global variable always because
1) it makes my intention clear
2) if I later decided to modify the global variable, I would be less
likely to introduce a bug by forgetting to declare it global.

Jul 8 '06 #14
On Fri, 07 Jul 2006 19:41:36 -0400, Luis M. González <lu*****@gmail.com>
wrote:
..
..
OK, so I should include the global only if I plan to modify it.
Otherwise, I don't need to include it. Am I right?
Correct. Globals are always available to read from. You need to declare
them if you want to modify them in another scope. Like nate, I also tend
to declare them all the time if I am going to use them, just for clarity.

M.
Jul 8 '06 #15

Markus Wankus wrote:
On Fri, 07 Jul 2006 19:41:36 -0400, Luis M. González <lu*****@gmail.com>
wrote:
.
.
OK, so I should include the global only if I plan to modify it.
Otherwise, I don't need to include it. Am I right?

Correct. Globals are always available to read from. You need to declare
them if you want to modify them in another scope. Like nate, I also tend
to declare them all the time if I am going to use them, just for clarity.

M.
Thank you guys!
Luis

Jul 8 '06 #16
Luis M. González a écrit :
Bruno Desthuilliers wrote:
>>def doIt(name=None):
global gname
if name is None:
name = gname
else:
gname = name


Sorry for this very basic question, but I don't understand why I should
add the global into the function body before using it.
You have to do it if you intend to rebind the name in the function's
body (else this would create the name in the local namespace).
This function works even if I don't add the global.
Just to try this out, I wrote this variant:

gname = 'Luis'

def doIt2(name=None):
if name is None:
name = gname
return name

Please read more carefully the OP's code:
"""
gname = 'Sue'
def doIt(name = gname):
global gname
gname = name
print 'doIt name', name, 'gname', gname
"""

As you can see, it rebinds gname.
print doIt2() --returns Luis.

So, what's the point of writing the function this way instead?

def doIt2(name=None):
global gname
if name is None:
name = gname
return name
In this case, you don't need the global statement (but keeping it makes
clear you're using a global name, which is not a bad thing in itself...)

Now if it's about LOCs count, here's a shorter equivalent:
doIt3 = lambda name : (name, gname)[name is None]
Jul 9 '06 #17
Luis M. González a écrit :
(snip)
OK, so I should include the global only if I plan to modify it.
Otherwise, I don't need to include it. Am I right?
s/modify/rebind/
Jul 9 '06 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: lawrence | last post by:
I get the impression that most people who are using objects in their PHP projects are mixing them with procedural code. The design, I think, is one where the procedural code is the client code, and...
5
by: Frostillicus | last post by:
I'm trying to use array_multisort to sort by one of the dimensions of an array stored in $GLOBALS like this: array_multisort($GLOBALS, SORT_STRING, SORT_DESC); Each "row" in $GLOBALS contains...
7
by: John | last post by:
Hi, I'm looking for the best way to deal with globals in PHP. As a 'C' software developer, I would normally avoid all globals and not have any at all, but use structs and pass everything in...
3
by: Robert Dodier | last post by:
Hello, I'm interested in introducing new variables into the environment of a Python interpreter or program. In reading through old posts to this newsgroup, I see there is an often-repeating...
45
by: It's me | last post by:
I am new to the Python language. How do I do something like this: I know that a = 3 y = "a" print eval(y)
2
by: comp.lang.php | last post by:
I came up with functions that I thought would do the trick: if (!function_exists('smtp_close')) { /** * This function will close a socket resource handle * * Original function found at...
2
by: xml0x1a | last post by:
How do I use exec? Python 2.4.3 ---- from math import * G = 1 def d(): L = 1 exec "def f(x): return L + log(G) " in globals(), locals() f(1)
5
by: Steven W. Orr | last post by:
I have two seperate modules doing factory stuff which each have the similar function2: In the ds101 module, def DS101CLASS(mname,data): cname = mname+'DS101' msg_class = globals() msg =...
1
by: cokofreedom | last post by:
if __name__ == '__main__': print "Globals (For Loop):" try: for i in globals(): print "\t%s" % i except RuntimeError: print "Only some globals() printed\n" else: print "All globals()...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.