473,320 Members | 2,112 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,320 software developers and data experts.

Turn of globals in a function?


Is there a way to hide global names from a function or class?

I want to be sure that a function doesn't use any global variables by
mistake. So hiding them would force a name error in the case that I
omit an initialization step. This might be a good way to quickly
catch some hard to find, but easy to fix, errors in large code blocks.

Examples:

def a(x):
# ...
x = y # x is assigned to global y unintentionally.
# ...
return x

def b(x):
# hide globals somehow
# ...
x = y # Cause a name error
# ...
return x
y = True
a(False): True
b(False):

*** name error here ***
Ron_Adam
Jul 18 '05 #1
8 2167
Ron_Adam wrote:
Is there a way to hide global names from a function or class?

I want to be sure that a function doesn't use any global variables by
mistake. So hiding them would force a name error in the case that I
omit an initialization step. This might be a good way to quickly
catch some hard to find, but easy to fix, errors in large code blocks.

Examples:

def a(x):
# ...
x = y # x is assigned to global y unintentionally.
# ...
return x

def b(x):
# hide globals somehow
# ...
x = y # Cause a name error
# ...
return x
y = True

a(False):
True

b(False):
*** name error here ***
Ron_Adam

For testing, you could simply execute the function in an empty dict:
a = "I'm a"
def test(): ... print a
... test() I'm a exec test.func_code in {} Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 2, in test
NameError: global name 'a' is not defined
This would get more complicated when you wanted to test calling with parameters,
so with a little more effort, you can create a new function where the globals
binding is to an empty dict:
from types import FunctionType as function
testtest = function(test.func_code, {})
testtest() Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 2, in test
NameError: global name 'a' is not defined


HTH

Michael

Jul 18 '05 #2
On Sat, 26 Mar 2005 20:01:28 GMT, Ron_Adam <ra****@tampabay.rr.com> wrote:

Is there a way to hide global names from a function or class?

I want to be sure that a function doesn't use any global variables by
mistake. So hiding them would force a name error in the case that I
omit an initialization step. This might be a good way to quickly
catch some hard to find, but easy to fix, errors in large code blocks.

Examples:

def a(x):
# ...
x = y # x is assigned to global y unintentionally.
# ...
return x

def b(x):
# hide globals somehow
# ...
x = y # Cause a name error
# ...
return x

If you put the above def b in e.g. a_module.py,
and do a (untested ;-)

from a_module import b

instead of defining it locally, then the global references
from b (and whatever else you import from a_module)
should be to the global dict defined for a_module (i.e., its
outermost scope), not to the globals where you do the import.
y = True
a(False):True Should work if you define a in place having same scope as the y assignmentb(False):

*** name error here ***

UIAM it should do this if you import b as above.

Regards,
Bengt Richter
Jul 18 '05 #3
On Sat, 26 Mar 2005 12:18:39 -0800, Michael Spencer
<ma**@telcopartners.com> wrote:
Ron_Adam wrote:
Is there a way to hide global names from a function or class?

I want to be sure that a function doesn't use any global variables by
mistake. So hiding them would force a name error in the case that I
omit an initialization step. This might be a good way to quickly
catch some hard to find, but easy to fix, errors in large code blocks.

Examples:

def a(x):
# ...
x = y # x is assigned to global y unintentionally.
# ...
return x

def b(x):
# hide globals somehow
# ...
x = y # Cause a name error
# ...
return x
y = True

>a(False):
True

>b(False):


*** name error here ***
Ron_Adam

For testing, you could simply execute the function in an empty dict:
>>> a = "I'm a"
>>> def test(): ... print a
... >>> test() I'm a >>> exec test.func_code in {} Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 2, in test
NameError: global name 'a' is not defined >>>

I didn't know you could do that. Interesting. :)

I was hoping for something in line that could use with an assert
statement. But this is good too, I'll have to play around with it a
bit. Thanks.

Ron

This would get more complicated when you wanted to test calling with parameters,
so with a little more effort, you can create a new function where the globals
binding is to an empty dict:
>>> from types import FunctionType as function
>>> testtest = function(test.func_code, {})
>>> testtest() Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 2, in test
NameError: global name 'a' is not defined >>>


HTH

Michael

Jul 18 '05 #4
If you put the above def b in e.g. a_module.py,
and do a (untested ;-)

from a_module import b

instead of defining it locally, then the global references
from b (and whatever else you import from a_module)
should be to the global dict defined for a_module (i.e., its
outermost scope), not to the globals where you do the import.
y = True
>a(False):

True

Should work if you define a in place having same scope as the y assignment
>b(False):

*** name error here ***

UIAM it should do this if you import b as above.

Regards,
Bengt Richter


Good suggestion. Thanks. I was somewhat aware of the modular scope,
but was looking for way to apply it on a more local level. Michael's
suggestion looks interesting for that.

Ron_Adam

Jul 18 '05 #5
Ron_Adam <ra****@tampabay.rr.com> wrote in message news:<6q********************************@4ax.com>. ..
Is there a way to hide global names from a function or class?

I want to be sure that a function doesn't use any global variables by
mistake. So hiding them would force a name error in the case that I
omit an initialization step. This might be a good way to quickly
catch some hard to find, but easy to fix, errors in large code blocks.


def noglobals(f):
.. import new
.. return new.function(
.. f.func_code,
.. {'__builtins__':__builtins__},
.. f.func_name,
.. f.func_defaults,
.. f.func_closure
.. )

You can use it with the Python 2.4 @decorator syntax:

@noglobals
def a(...):
.. # code here

Doing this for a class is a little more work. You will need dig inside
to perform this treatment on each method separately and handle new and
old-style classes a bit differently.

Note that this kind of function may declare globals. They will be
persistent but private to the function.

Oren
Jul 18 '05 #6
On 26 Mar 2005 22:51:14 -0800, or**@REMOVETHIS1.hishome.net (Oren
Tirosh) wrote:
Ron_Adam <ra****@tampabay.rr.com> wrote in message news:<6q********************************@4ax.com>. ..
Is there a way to hide global names from a function or class?

I want to be sure that a function doesn't use any global variables by
mistake. So hiding them would force a name error in the case that I
omit an initialization step. This might be a good way to quickly
catch some hard to find, but easy to fix, errors in large code blocks.


def noglobals(f):
. import new
. return new.function(
. f.func_code,
. {'__builtins__':__builtins__},
. f.func_name,
. f.func_defaults,
. f.func_closure
. )

You can use it with the Python 2.4 @decorator syntax:

@noglobals
def a(...):
. # code here


Cool! I haven't played with decorators yet. :)

I noticed the 'new' module is depreciated. It referred me to call the
object type directly instead. So this is probably the better way.

def noglobals(f):
return type(f)(
f.func_code,
{'__builtins__':__builtins__},
f.func_name,
f.func_defaults,
f.func_closure )

@noglobals
def a():
global x
try: x
except: x=0
x += 1
return x

x = 5
for n in range(10):
print a()
print x # x is still 5
So this is another, but longer, way to do a generator.

print type(a).__doc__ function(code, globals[, name[, argdefs[, closure]]])

Create a function object from a code object and a dictionary.
The optional name string overrides the name from the code object.
The optional argdefs tuple specifies the default argument values.
The optional closure tuple supplies the bindings for free variables.


What are 'free variables'?

And is there a way to directly read what names in a function are set
with the global statement? (Other than looking at the monitor. ;)

Ron_Adam

Jul 18 '05 #7
Oren Tirosh wrote:
def noglobals(f):
. import new
. return new.function(
. f.func_code,
. {'__builtins__':__builtins__},
. f.func_name,
. f.func_defaults,
. f.func_closure
. )


Be aware that this will render the function incapable
of seeing *any* globals at all, including other
functions and classes defined in the same module --
which you may find rather inconvenient!

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg
Jul 18 '05 #8
On Thu, 31 Mar 2005 16:28:15 +1200, Greg Ewing
<gr**@cosc.canterbury.ac.nz> wrote:
Oren Tirosh wrote:
def noglobals(f):
. import new
. return new.function(
. f.func_code,
. {'__builtins__':__builtins__},
. f.func_name,
. f.func_defaults,
. f.func_closure
. )


Be aware that this will render the function incapable
of seeing *any* globals at all, including other
functions and classes defined in the same module --
which you may find rather inconvenient!

Developing this idea further...

This allows a programmer to specify what globals to allow read and or
writes.
Cheers,
Ron
#---start---
# useglobals.py

"""
A function to specify what globals and builtins
a function may access.
Author: Ronald Adam
"""

def useglobals(rw_globals=None, r_globals=None, builtins=True):
#import dis
import sys
write_list = []
read_list = []
if rw_globals != None:
rw_globals = rw_globals.replace(' ','')
write_list = rw_globals.split(',')
if r_globals != None:
r_globals = r_globals.replace(' ','')
read_list = r_globals.split(',')
if builtins == True:
read_list.extend(dir(__builtins__))
elif builtins != None:
builtins = builtins.replace(' ','')
read_list.extend(builtins.split(','))
# Add own name to read list.
read_list.append(sys._getframe(0).f_code.co_name)
read_list.extend(write_list)
#print read_list, write_list
names = sys._getframe(1).f_code.co_names
code = sys._getframe(1).f_code.co_code
#print dis.disassemble(sys._getframe(1).f_code)
i = 0
while i < len(code):
#print ord(code[i])
op = ord(code[i])
if op == 116: # dis.opmap['LOAD_GLOBAL']
oparg = ord(code[i+1]) + ord(code[i+2]) * 256
if str(names[oparg]) not in read_list:
raise NameError, "read from global name %s, detected"
% names[oparg]
elif op == 97: # dis.opmap['STORE_GLOBAL']
oparg = ord(code[i+1]) + ord(code[i+2]) * 256
if names[oparg] not in write_list:
raise NameError, "write to global name %s, detected" %
names[oparg]
if op >= 90: # dis.HAVE_ARGUMENT
i += 3 # Not sure if this is always the same?
else:
i += 1
if __name__ == '__main__':
"""
Test useglobals() function. Change values to test
for error catching.
"""

def a():
useglobals(rw_globals='x', r_globals='y,b')
# This function can read or write 'x',
# Can read 'y', and function 'b',
# and can access all builtins.
global x
y = 5
x += y
x = b(x)
return x

def b(g):
useglobals('','y,c','int')
# This function can only read 'y' and
# function 'c' in globals, and can
# only access 'int' in builtins.
g = g+y
c(int(g))
return g

def c(w):
useglobals(builtins=None)
# This function has no builtins or globals.
w = w**2
return w

y = 4
x = 5
z = 6
print a(),x,y,z

#---end---

Jul 18 '05 #9

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

Similar topics

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...
2
by: tedsuzman | last post by:
----- def f(): ret = 2 exec "ret += 10" return ret print f() ----- The above prints '12', as expected. However,
6
by: Paddy | last post by:
Hi, I got tripped up on the way eval works with respect to modules and so wrote a test. It seems that a function carries around knowledge of the globals() present when it was defined. (The...
2
by: Ron_Adam | last post by:
Using this example: def whatisx(): try: print 'x is',x except: print 'There is no x'
11
by: Matt | last post by:
Hello, I'm rather new to C++ and have a question about globals. What is the big deal about them? They make things much easier to program because you don't have to worry about all the passing...
4
by: Angelos Devletoglou | last post by:
Hi... It drives me nuts this server. My php.ini says that register_globals is OFF and when I run phpinfo() it says they are ON. I restarted both httpd and the whole server still nothing. IS...
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 =...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

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.