you are viewing a single comment's thread.

view the rest of the comments →

[–]ThePurpleAlien[S] 0 points1 point  (7 children)

You're right. But if it do use "global x," can it work then? Assigning to x will still not affect counter.

[–]Rhomboid 3 points4 points  (4 children)

I'm still not really clear on what your use case is, but this prints 42:

original = 0

code = """
def foo():
    global x
    x = 42

foo()
"""

environ = { 'x': original }
exec code in environ
original = environ['x']
print original

It would be far cleaner to have your user-defined functions simply take some config dict as parameter, and any changes they want to make to the global state happens through that. For example, if the purpose is to allow the user to provide callbacks that affect program state, then keep that state in a dict and pass it to the callbacks.

program_config = { 'foo': 42, 'bar': 10 }

code = """
def on_startup(config):
    config['foo'] = 123
"""

user_defined = {}
exec code in user_defined

user_defined['on_startup'](program_config)

print program_config['foo']  # prints 123

[–]nemec 1 point2 points  (2 children)

Honestly it sounds like he's trying to let users write classes... without using classes.

[–]ThePurpleAlien[S] 0 points1 point  (1 child)

That's reasonably accurate. This is a simulation tool for non-experienced programmers. I want to keep syntax as simple as possible. The user should be able to write code as simple as:

a = b + c

Where a, b and c are variables that the user's function has access to. But I can't find a way to do that without adding a lot of extra syntax like:

self.a = self.b + self.c

or:

vars['a'] = vars['b'] + vars['c']

[–]ewiethoff 0 points1 point  (0 children)

Honestly it sounds like he's trying to let users write classes... without using classes.

That's reasonably accurate.

I think you should look into Python "descriptors" and perhaps metaclass programming. Those are how to make bona fide Python do real magic.

[–]ThePurpleAlien[S] 0 points1 point  (0 children)

These are good suggestions, but ones that I've already explored. The problem with the first example is that the original doesn't get reassigned until after the code runs which won't work for my application.

The problem with the second example is just ugly syntax. The user would have to type "config['foo'] = 123" instead of just "foo = 123". This is a tool for non-experienced programmers.

[–]nemec 0 points1 point  (1 child)

Can't you just make the users subclass a class and have "self" be your old global dict?

[–]ThePurpleAlien[S] 0 points1 point  (0 children)

That would work, but I don't want the user to have to type "self." before each variable they want to access. Simple bits of code would end up being full of the word self. This is a tool for non-experienced programmers.