473,805 Members | 2,010 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

func_code vs. string problem

Each function has a func_code property that is suposed to contain the
pure bytecode of the function. All the context (including reference to
relevant namespaces) is stored in different fields of the function
object. Since 'exec' is able to execute any string or bytecode in the
current scope, it would seem possible to execute code of any function
in any namespace. But no matter how I tried, I could not do it. There
must be something I am missing.
Here's what I do: (if anyone wants to help, I placed the source
under http://www.bajobongo.net/foo.py - tested on Python 2.4.1)

1. I declare a function. In the next steps I will try to run its code
from inside a class:

def myfunction():
print abc
self.test()

2. I declare a class foo, with two methods. The first one tries to
reach some local variables from a string passed to exec. The other one
tries to do the same from inside a bytecode (from myfunction). IMHE
this should make no difference to 'exec' - [spoiler: it does].

class foo:
def test(self):
print "ABC"
def checkfunction(s elf):
abc=10
exec myfunction.func _code
def checkstring(sel f):
abc=10
exec "print abc;self.test() "

3. I test the both methods. Sadly, the 'checkfunction' fails to find
the correct namespace (id does not see 'abc' nor 'self'). Adding
things like:
"exec myfunction.func _code in globals(),local s()" does not help.

i=foo()
i.checkstring()
i.checkfunction () # this throws exception; why???

4. I try to find some help here, and hope to also gain better
undesrtanding of how Python works :-)

Thanks for any suggestions,
regards,
Filip Dreger
Jul 19 '05 #1
8 2197
I came up with a simpler description of the problem.
It's all in the simple source:

# we define 'print b' in three different ways: as a string,
# a bytecode and a function
string="print b"
code=compile(st ring,'string',' exec')
def function():
print b

# now we make functions that test if it is possible to execute 'print
b'
# in some local scope

def execstring():
b=5
exec string

def execfunction():
b=5
exec function.func_c ode

def execcode():
b=5
exec code

execstring() # works
execcode() # works
execfunction() # throws name error exception...

My problem is that both 'string' and 'code' are references to code
objects, so they _should_ behave in the same way... I am close to
giving up...
I am trying to find a way of executing functions without creating a
nested scope, so they can share local and global namespace (even if
they are declared in some other module). I _could_ turn them into
strings and pass around as compiled objects, butthis would be very
ugly. I am sure Python has some better, cleaner way to do this.

regards,
Filip Dreger
Jul 19 '05 #2
Filip Dreger wrote:
Each function has a func_code property that is suposed to contain the
pure bytecode of the function. All the context (including reference to
relevant namespaces) is stored in different fields of the function
object. Since 'exec' is able to execute any string or bytecode in the
current scope, it would seem possible to execute code of any function
in any namespace. But no matter how I tried, I could not do it. There
must be something I am missing.
Here's what I do: (if anyone wants to help, I placed the source
under http://www.bajobongo.net/foo.py - tested on Python 2.4.1)

1. I declare a function. In the next steps I will try to run its code
from inside a class:

def myfunction():
print abc
self.test()

2. I declare a class foo, with two methods. The first one tries to
reach some local variables from a string passed to exec. The other one
tries to do the same from inside a bytecode (from myfunction). IMHE
this should make no difference to 'exec' - [spoiler: it does].

class foo:
def test(self):
print "ABC"
def checkfunction(s elf):
abc=10
exec myfunction.func _code
def checkstring(sel f):
abc=10
exec "print abc;self.test() "

3. I test the both methods. Sadly, the 'checkfunction' fails to find
the correct namespace (id does not see 'abc' nor 'self'). Adding
things like:
"exec myfunction.func _code in globals(),local s()" does not help.

i=foo()
i.checkstring()
i.checkfunction () # this throws exception; why???


See the documentation:

http://docs.python.org/ref/dynamic-features.html

"""The eval(), execfile(), and input() functions and the exec statement
do not have access to the full environment for resolving names. Names
may be resolved in the local and global namespaces of the caller. Free
variables are not resolved in the nearest enclosing namespace, but in
the global namespace."""

Note the last sentence, which tells you that your free variable, 'abc',
will be resolved in the *global* namespace. In your particular problem,
you can solve this by substituting your local namespace for the global
namespace:

py> def myfunction():
.... print abc
.... self.test()
....
py> class foo:
.... def test(self):
.... print "ABC"
.... def checkfunction(s elf):
.... abc=10
.... exec myfunction.func _code in locals()
.... def checkstring(sel f):
.... abc=10
.... exec "print abc;self.test() "
....
py> foo().checkstri ng()
10
ABC
py> foo().checkfunc tion()
10
ABC

But note that if your code actually needs access to any globals, it's
out of luck:

py> def myfunction():
.... print foo
.... print abc
.... self.test()
....
py> foo().checkfunc tion()
Traceback (most recent call last):
File "<interacti ve input>", line 1, in ?
File "<interacti ve input>", line 6, in checkfunction
File "<interacti ve input>", line 2, in myfunction
NameError: global name 'foo' is not defined

One possible workaround might be:

py> class foo:
.... def test(self):
.... print "ABC"
.... def checkfunction(s elf):
.... abc=10
.... l = locals()
.... l.update(global s())
.... exec myfunction.func _code in l
.... def checkstring(sel f):
.... abc=10
.... exec "print abc;self.test() "
....
py> foo().checkfunc tion()
__main__.foo
10
ABC

But I'd have to know what your real use case is to tell you whether or
not this is worth the trouble. Why do you want to exec the func_code
anyway? Why can't you just call the function?

STeVe
Jul 19 '05 #3
Filip Dreger wrote:
I am trying to find a way of executing functions without creating a
nested scope, so they can share local and global namespace (even if
they are declared in some other module).


Why? Can you explain what the use case is?

STeVe
Jul 19 '05 #4

Uzytkownik "Steven Bethard" <st************ @gmail.com> napisal w
wiadomosci news:Qv******** ************@co mcast.com...
Filip Dreger wrote:
I am trying to find a way of executing functions without creating a
nested scope, so they can share local and global namespace (even if
they are declared in some other module).


Why? Can you explain what the use case is?


I have a large set of objects of a single class - 'actor'. They are
created all at once, and they all live in a sort of container written
in C. The methods of the functions are few and general. One of them is
simply 'act()', that is called by the C program every X seconds (tics,
whatever).
Each object can play 0..N roles, and the roles played by an object
often change during its lifetime. The roles should be played in the
act() method. Also, the roles should be defined in some simple way,
and in an external python file (so adding/removing roles does not
require recompiling of the parts embedded in C).

If I had a magic function 'exec in current scope' I would implement it
like this:

class actor:
def __init__():
self.roles=[]
def act():
for i in self.roles:
exec i in current scope

then the roles would simply be functions defined in any importable
file. For example creating an actor that logs each time it is called
would be as simple as:

import actor

def log():
self.counter+=1
print "called %d times"%self.cou nter

a=actor.actor()
a.counter=0
a.roles.append( log)

Let me recapitulate (is that the right English word?):
1. I need to keep the definitions of roles in a separate file (they
can not simply be additional methods)
2. I need the roles to have full access to global and local namespace
of the actor object (sometimes they have to change it, and sometimes
they have to use some external modules) - the roles should work like
plugins.
3. I guess I also need a fresh look at the problem. Maybe I am simply
going the wrong way? I am more than willing to change my design, if
someone shows me the light :-)

regards,
Filip Dreger
Jul 19 '05 #5
Filip Dreger wrote:
If I had a magic function 'exec in current scope' I would implement it
like this:

class actor:
def __init__():
self.roles=[]
def act():
for i in self.roles:
exec i in current scope

then the roles would simply be functions defined in any importable
file. For example creating an actor that logs each time it is called
would be as simple as:

import actor

def log():
self.counter+=1
print "called %d times"%self.cou nter

a=actor.actor()
a.counter=0
a.roles.append( log)
Any reason you can't define it like:

class actor(object):
def __init__(self):
self.roles = []
def act(self):
for role_func in self.roles:
role_func(self)

And then write your other modules like:

import actor

def log(self):
self.counter += 1
print "called %d times"%self.cou nter

a = actor.actor()
a.counter = 0
a.roles.append( log)

The only real difference here is that log is basically declared as an
instance method. So if you need to update actor.actor state, you simply
modify the self object.
2. I need the roles to have full access to global and local namespace
of the actor object (sometimes they have to change it, and sometimes
they have to use some external modules) - the roles should work like
plugins.


By importing actor, they have full access to the global namespace of the
actor.actor object, by simply accessing the actor module attributes.

So the issue here is really about full *local* namespace access. Do you
really need *full* local namespace access? Why isn't access to the
actor.actor instance sufficient?

STeVe
Jul 19 '05 #6
Uzytkownik "Steven Bethard" <st************ @gmail.com> napisal w
wiadomosci news:04******** ************@co mcast.com...
See the documentation:

http://docs.python.org/ref/dynamic-features.html

"""The eval(), execfile(), and input() functions and the exec
statement do not have access to the full environment for resolving
names. Names may be resolved in the local and global namespaces of
the caller. Free variables are not resolved in the nearest enclosing
namespace, but in the global namespace."""
Thank you! I feel silly I have not found the piece of instruction
myself. And even worse, as I still do not understand: if exec()
resolves free bariable names in the global namespace, how come it
works well with code in a string? Or with a code in a compiled string?
Note the last sentence, which tells you that your free variable,
'abc', will be resolved in the *global* namespace. In your
particular problem, you can solve this by substituting your local
namespace for the global namespace.
This particular problem - sadly - is a simplified version of the real
one. I need access to both: global and local namespaces, so this
solution is not for me.
The manual says I can pass two dictionaries to exec, one for global
namespace and one for local. But, strange as it seems, I could not get
it to work. In the example I gave, changing exec f.func_code to exec
f.func_code in globals(),local s() does not help a bit.
One possible workaround might be:

py> class foo:
... def test(self):
... print "ABC"
... def checkfunction(s elf):
... abc=10
... l = locals()
... l.update(global s())
... exec myfunction.func _code in l
... def checkstring(sel f):
... abc=10
... exec "print abc;self.test() "
...
py> foo().checkfunc tion()
__main__.foo
10
ABC
I thought about that... I don't know why, but it seems wrong. Maybe
the updating dictionaries is not very expensive, but there must be
some better way. This code has a 'workaround - fixme' written all over
it.
Up to now, each time I encountered such a workaroundish solution, it
turned out Python has a cleaner way to do it. I sure hope this is also
the case here :-).
But I'd have to know what your real use case is to tell you whether
or not this is worth the trouble. Why do you want to exec the
func_code anyway? Why can't you just call the function?


I put the description in the other post. Perhaps it's jkust my design
that's broken.
Thanks again.

regards,
Filip Dreger
Jul 19 '05 #7
Filip Dreger wrote:
Uzytkownik "Steven Bethard" <st************ @gmail.com> napisal w
wiadomosci news:04******** ************@co mcast.com...
See the documentation:

http://docs.python.org/ref/dynamic-features.html

"""The eval(), execfile(), and input() functions and the exec
statement do not have access to the full environment for resolving
names. Names may be resolved in the local and global namespaces of
the caller. Free variables are not resolved in the nearest enclosing
namespace, but in the global namespace."""
Thank you! I feel silly I have not found the piece of instruction
myself. And even worse, as I still do not understand: if exec()
resolves free bariable names in the global namespace, how come it
works well with code in a string? Or with a code in a compiled string?


Well, probably the best thing to do is to check out what byte-code is
generated in each case:

py> s = compile('print b', 'string', 'exec')
py> def f():
.... print b
....
py> import dis
py> dis.dis(s)
1 0 LOAD_NAME 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
py> dis.dis(f)
2 0 LOAD_GLOBAL 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE

So, the code is basically identical, except that with the string, the
code uses LOAD_NAME, while with the function, the code uses LOAD_GLOBAL.
Note that this is because Python can tell that b is not defined in the
function, and so it assumes that is must be a global lookup. Look what
happens if I give f a parameter:

py> def f(b):
.... print b
....
py> dis.dis(f)
2 0 LOAD_FAST 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE

Now f is using LOAD_FAST, which looks at the locals. I believe the
point of LOAD_GLOBAL and LOAD_FAST (instead of always using LOAD_NAME)
is to increase performance in the common case, where exec is not used.

Seems like the documentation is being a little conservative -- it does
look like some statements will do the lookup in the locals too... If I
was more confident about what goes on here, I'd probably try to file a
documentation bug...
The manual says I can pass two dictionaries to exec, one for global
namespace and one for local. But, strange as it seems, I could not get
it to work. In the example I gave, changing exec f.func_code to exec
f.func_code in globals(),local s() does not help a bit.
That's because, as the dis.dis output above shows, the function you've
defined is only searching the global namespace. So the locals() dict
you pass won't ever be looked at.

[snip example using locals as globals]
I thought about that... I don't know why, but it seems wrong. Maybe
the updating dictionaries is not very expensive, but there must be
some better way. This code has a 'workaround - fixme' written all over
it.


Yeah, I agree. On the other hand, whenever I see exec, it has
'workaround - fixme' written all over it too. ;)

STeVe
Jul 19 '05 #8

Uzytkownik "Steven Bethard" <st************ @gmail.com> napisal w
wiadomosci news:FL******** ************@co mcast.com...
Any reason you can't define it like:

class actor(object):
def __init__(self):
self.roles = []
def act(self):
for role_func in self.roles:
role_func(self) [snip] By importing actor, they have full access to the global namespace of
the actor.actor object, by simply accessing the actor module
attributes.

So the issue here is really about full *local* namespace access. Do
you really need *full* local namespace access? Why isn't access to
the actor.actor instance sufficient?


!!! Yep, of course it is sufficient. Abondoning the obvious
role_func() must have had some good reasons some time ago, but now I
can not even remember them, probably they were not so important :-)
Thanks a million,
Filip
Jul 19 '05 #9

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

Similar topics

7
10632
by: Forecast | last post by:
I run the following code in UNIX compiled by g++ 3.3.2 successfully. : // proj2.cc: returns a dynamic vector and prints out at main~~ : // : #include <iostream> : #include <vector> : : using namespace std; : : vector<string>* getTyphoon()
17
14366
by: Olivier Bellemare | last post by:
I've tried to make a function that returns the middle of a string. For example: strmid("this is a text",6,4); would return "is a". Here is my code: char *strmid(char *texte, int depart, int longueur) { char *resultat = " "; char *temporaire = " "; int nbr;
51
8300
by: Alan | last post by:
hi all, I want to define a constant length string, say 4 then in a function at some time, I want to set the string to a constant value, say a below is my code but it fails what is the correct code? many thx!
4
8830
by: Simon Schaap | last post by:
Hello, I have encountered a strange problem and I hope you can help me to understand it. What I want to do is to pass an array of chars to a function that will split it up (on every location where a * occurs in the string). This split function should allocate a 2D array of chars and put the split results in different rows. The listing below shows how I started to work on this. To keep the program simple and help focus the program the...
18
7199
by: Steve Litvack | last post by:
Hello, I have built an XMLDocument object instance and I get the following string when I examine the InnerXml property: <?xml version=\"1.0\"?><ROOT><UserData UserID=\"2282\"><Tag1 QID=\"55111\"><Tag2 AID=\"5511101\"></Tag2></Tag1><Tag1 QID=\"55112\"><Tag2 AID=\"5511217\"></Tag2></Tag1><Tag1 QID=\"5512282\"><Tag2 AID=\"551228206\"></Tag2></Tag1><Tag1 QID=\"55114\"><Tag2 AID=\"5511406\"></Tag2></Tag1><Tag1 QID=\"55115\"><Tag2
32
14917
by: tshad | last post by:
Can you do a search for more that one string in another string? Something like: someString.IndexOf("something1","something2","something3",0) or would you have to do something like: if ((someString.IndexOf("something1",0) >= 0) || ((someString.IndexOf("something2",0) >= 0) ||
4
5282
by: MooMaster | last post by:
After some google searching on the forum I couldn't find any topics that seemed to relate exactly to my problem, so hopefully someone can help me out... I'm running python 2.4.1 on a local Win2K system and doing some work-related development on an AIX box, and I'm running into a problem using cx_Oracle to add some information to an Oracle 9.2 table. I have a table_title defined as a VARCHAR2 data type, and when I'm trying to retrieve...
6
2220
by: tommaso.gastaldi | last post by:
Hi, does anybody know a speedy analog of IsNumeric() to check for strings/chars. I would like to check if an Object can be treated as a string before using a Cstr(), clearly avoiding the time and resource consuming Try... Catch, which in iterative processing is totally unacceptable. -tom
1
8379
Atli
by: Atli | last post by:
The following small HowTo is a compilation of an original problem in getting some cookie-values through different methods of string-handling. The original Problem was posted as follows: As you can see, there could have been a problem with the split-method. The following short article handles ways around this possible problem, that we couldn't reproduce, but someone may possibly encounter it too sometimes. If nothing else, the shown...
0
9718
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9596
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10613
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10368
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7649
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6876
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5544
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5678
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3008
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.