sort of a beginner question about globals

F

fred.dixon

i have read the book and searched the group too
----------------------------------------------
im not gettin it.
i want to read a global (OPTIONS) from file1 from a class method
(func1) in file2
i want to understand how this works.


----------------------------------------------
#file1.py
import file2
import sys

OPTION = sys.argv[1:]
pass
a=global2.class1()
a.func1()


#file2.py
import __main__
pass
class class1:
.. def func1(self):
.. pass
-------------------------------------------
 
S

Steven Bethard

fred.dixon said:
i have read the book and searched the group too
----------------------------------------------
im not gettin it.
i want to read a global (OPTIONS) from file1 from a class method
(func1) in file2
i want to understand how this works.

----------------------------------------------
#file1.py
import file2
import sys

OPTION = sys.argv[1:]
pass
a=global2.class1()
a.func1()


#file2.py
import __main__
pass
class class1:
. def func1(self):
. pass
-------------------------------------------

----- file1.py -----
import file2

a = file2.class1()
a.func1()
--------------------

----- file2.py -----
class class1(object):
def func1(self):
pass
--------------------

I don't see what you want OPTION for, so I've removed it. If you can
explain your intentions better, maybe I can help more.

STeVe
 
F

fred.dixon

I want to use OPTIONS as a global var.
In this particular case I am trying to set a global debug constant so I
can have some debug logging happen when my program is run with a
-debug option.
what will actuall end up in OPTIONS is OPTIONS.debug = True as i am
using optparse module.
 
S

Steven Bethard

fred.dixon said:
I want to use OPTIONS as a global var.
In this particular case I am trying to set a global debug constant so I
can have some debug logging happen when my program is run with a
-debug option.
what will actuall end up in OPTIONS is OPTIONS.debug = True as i am
using optparse module.

Why not just make options a module?

Then you can do something like:

----- options.py -----
debug = False
----------------------

----- file1.py -----
import file2
import options

options.debug = True
a = file2.class1()
a.func1()
--------------------

----- file2.py -----
import options
class class1(object):
def func1(self):
if options.debug:
print 'Debugging'
pass
--------------------

Note that if you're trying to output debugging messges, you should
really look into the logging module instead.

STeVe
 
F

fred.dixon

how would i use the following if OPTIONS was in a module ?
-----------------------
from optparse import OptionParser

usage = "usage: %prog [options] arg"
parser = OptionParser(usage)

parser.add_option("-d", "--debug", ction="store_true", dest="verbose")
(OPTIONS = parser.parse_args()

ps
Im not anywhere near my program right now just doing some kunch time
surfing.
 
S

Steven Bethard

fred.dixon said:
how would i use the following if OPTIONS was in a module ?
-----------------------
from optparse import OptionParser

usage = "usage: %prog [options] arg"
parser = OptionParser(usage)

parser.add_option("-d", "--debug", ction="store_true", dest="verbose")
(OPTIONS = parser.parse_args()

Just have this code update the options module:

import options
....
opts, args = parser.parse_args()
options.__dict__.update(opts.__dict__)

STeVe
 
F

fred.dixon

ok I'm sorry, I'm not sure what your doing there.
if i have to guess it looks like yo might me modifying the imported
modules dict with another dict.

isn't there a way i can just assign to a var and have it seen no matter
what part of the code is currently executing ?
 
F

fred.dixon

it seems that i can import __main__ where i set the global and then
access the var from my local func.

is ther any gotcha's involveld in this ?
 
S

Steven Bethard

fred.dixon said:
ok I'm sorry, I'm not sure what your doing there.
if i have to guess it looks like yo might me modifying the imported
modules dict with another dict.

Yes, this takes all the atrributes of the options object and sets them
as attributes of the module. If you're afraid of __dict__, you could
also write this as:

for name, value in vars(opts).iteritems():
setitem(options, name, value)
isn't there a way i can just assign to a var and have it seen no matter
what part of the code is currently executing ?

No, unless you mean only within a single module. Python has no globals
in the sense of being global to all modules. If globals in a single
module is sufficient, you can modify the globals of the current module
using globals(), e.g.:

globals()[name] = value

or in my example:

globals().update(vars(opts))

You can also do this by importing the module itself, e.g.:

mod = __import__(__name__)
setattr(mod, name, value)
it seems that i can import __main__ where i set the global and then
access the var from my local func.

is ther any gotcha's involveld in this ?

Probably. ;) But since I don't know what code you've actually produced
here, I'm not sure. What did you write to "import __main__ ... [and]
set the gloabl and then access the var"?

STeVe
 
F

fred.dixon

this is what i am using to test with.
my program is not much more involved just longer
and with a GUI.
I did test it and everything works, just wondered if there was
something evil and bad about importing main.
#------------------------------------------------
#global1.py
import global2
import global3
import sys

constant = 'dumb'
option = sys.argv[1:]
pass
#global2.func1()
a=global2.class1()
a.func1()
print newvar


#global2.py
import __main__
pass
class class1:
def func1(self):
__main__.newvar = "string"
pass
 
S

Steven Bethard

fred.dixon said:
#global1.py
import global2
import global3
import sys

constant = 'dumb'
option = sys.argv[1:]
pass
#global2.func1()
a=global2.class1()
a.func1()
print newvar

#global2.py
import __main__
pass
class class1:
def func1(self):
__main__.newvar = "string"
pass

The other ways of getting this behavior would be to write global2.py as:
class class1:
def func1(self):
global newvar
newvar = "string"
or
class class1:
def func1(self):
globals()["newvar"] = "string"
or
class class1:
def func1(self):
__import__(__name__).newvar = "string"
I don't know which of these is really preferred. Generally if I see
myself writing code like this, I figure I probably need to refactor things.

STeVe

P.S. Why are you writing all those 'pass' statements? They're not
necessary in any of the locations you've placed them.
 
F

fred.dixon

when i am roughing out my functions and classes i out a pass statement
as my first line just as a place holder and a convenient place to put a
break when i am testing. no other good reason.
 
D

Duncan Booth

fred.dixon said:
when i am roughing out my functions and classes i out a pass statement
as my first line just as a place holder and a convenient place to put a
break when i am testing. no other good reason.

A better idea when roughing out functions and classes is to insert a
docstring describing what the function is going to do. That way you don't
have to use 'pass' at all, and you don't have to remember to remove
anything when you later add code. Alternatively use 'raise
NotImplementedError' to tell you at runtime if you hit any such functions.

'convenient place to put a break when testing' implies you test by stepping
through with a debugger. You should consider writing unit tests as a way of
reducing the amount of debugging you need to do.
 
F

fred.dixon

:) unit test is something on my to-learn list. seems involved and i
haven't seen any straight forward tutorials yet. as yet i still
consider myself a hobbyist at best.
 
T

Thomas Heller

fred.dixon said:
:) unit test is something on my to-learn list. seems involved and i
haven't seen any straight forward tutorials yet. as yet i still
consider myself a hobbyist at best.

I would recommend "Test Driven Development" by Kent Beck
(Addison-Wesley).

Thomas
 
D

Duncan Booth

fred.dixon said:
:) unit test is something on my to-learn list. seems involved and i
haven't seen any straight forward tutorials yet. as yet i still
consider myself a hobbyist at best.
Hmm, I believe you are right. I can't see any straight-forward tutorials
which use Python. I found a tutorial at onlamp.com, but it doesn't seem to
me to explain TDD at all clearly.

Kent Beck's book is pretty good except that the main tutorial is in Java
rather than Python, and the Python section tells you how to write a new
unit test harness (using TDD). So it won't tell you how to use the unittest
module, but if you use the Python documentation for that (library
reference, chapter 5.3) you should be able to follow the Java tutorial
converting it into Python as you go. (Likewise, I've worked through the
Python chapter converting that into another language when there wasn't a
suitable xUnit harness available).

It is one of those things that, once you get the hang of it, really grows
on you: for me the turning point was the first time I added some code and a
completely unrelated test which had been working fine up until that point,
and which could not possibly be affected by the latest change, suddenly
broke. At that point I realised I had just saved myself considerable
debugging time as without the tests I wouldn't have realised I had
introduced a problem until much later.
 
S

Scott David Daniels

Duncan said:
Hmm, I believe you are right. I can't see any straight-forward tutorials
which use Python. I found a tutorial at onlamp.com, but it doesn't seem to
me to explain TDD at all clearly.

Here's a simple sketch of how to start:

Create a file named "test_prog.py" (where "prog.py" is the module you
are going to develop). Then stick in the following as the initial
contents of the file (I'm over-indenting by four here):

import unittest
import prog # this should be your module

class TestCase(unittest.TestCase):
def setUp(self):
self.whatever = 'build commonly used data'
# this picks up any setup common to any test case

def test_first(self):
'''Simplest functioning test use of our function'''
self.assertEqual(42, prog.magic(1)) # use a better test

def test_second(self):
'''magic should fail with an appropriate exceptions'''
self.assertRaises(TypeError, prog.magic, 'q')


if __name__ == '__main__':
unittest.main()


More details can be found in the unittest documentation, but this may
be enough to get you started testing. Essentially, new test cases
are added as methods on your class(es). setUp is called before each
test case, so saving a data structure as self.something eliminates
boilerplate at the top of every test; if you don't need anything in
common, don't bother defining setUp. The test methods should be
named "test_..."; the name is how unittest know which are test cases.
If you have a more elaborate setup for a bunch of tests, create a new
class as a subclass of unittest.TestCase (or eventually inherriting
from it). unittest uses all classes defined in the test_prog module
that are subclasses of unittest.TestCase.

To run all of these the tests, at a command prompt type:
python test_prog.py

To run them all and see which are being run,
python test_prog.py -v

You can run individual tests with:
python test_prog.py TestCase.test_second

TestCase here is the name of the class you chose to hold a block of test
cases. You can run all of the tests under a single class as:
python test_prog.py TestCase.test_second

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

fred.dixon

just read the ne stuuf. i went to DIP right after work anf found in
nice intro to unittest. not to bad (i thinK) now that I can see it work)
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top