Symbols as parameters?

Martin Drautzburg Martin.Drautzburg at web.de
Fri Jan 22 09:12:46 CET 2010


Steven D'Aprano wrote:

> I think this really is the correct solution for your problem. In
> Python, the standard place to have such public constants is at the
> module level, not the function or class. I think you're worrying
> unnecessarily about "namespace pollution" -- the module namespace is
> *exactly* the right place for them. If two functions both need UP,
> DOWN, etc symbols, then either:

Defining those symbols at the module level is absolutely fine with me.
The namespace pollution is indeed my biggest worry. You see, I want to
be able to type in lots of lines with little effort. Preferably I would
want to type

        move up

I could still live with

        move(up)

But then I need to import "from Movements import directions" or
something like that. If another module defines "up" in some different
way, I am in trouble. To circumvent this I would have to "import
Movements", but then I's have to write

        move(directions.up)

This is so noisy, I'd rather write

        move ("up")

I don't like the quotes. I don't mind that "up" is a string (as someone
suspected), what I dislike is that "up" was created ad-hoc by the
caller. Could it be move("UP") as well? You could not tell without
looking at the code of move(). Defining the symbols at module level
solves THIS problem, but it leaves the above other problems. Still I
like this best so far, because it is the standard way of doing this.

> You would force them to do this:
> 
> # Get some flags for compile:
> flags = re.compile.I & re.compile.M
> # ...
> # much later on
> # x = re.compile(s, flags)
> 
> which is, in my opinion, a needless level of indirection and possibly
> in violation of Demeter's Law.

So scoping should be at module level? That makes some sense.

> Either way, when you go to *use* the direction, you're still passing a
> string. There's no difference between:
> 
> move(m.UP)
> 
> and just
> 
> move("up")

The difference is that move(m.UPx) would automatically raise an
attribute error wheras move("upx") requires extra code in move() to
raise an exception. move("up") just looks sematically wrong to me, in
contrast len("up") is correct, because it really is an operation on
Strings. When the caller writes move(up) should should not (need to)
know what "up" really is behind the scenes.

>> (4) Finally someone mentioned DSLs. I guess thats absolutely correct.
>> This is what I am struggeling to achieve. I did a little googling
>> ("how to write DSLs in python"), but haven't found anything appealing
>> yet. Any pointers would be appreciated.
> 
> That truly is using a bulldozer to crack a peanut.

Well I guess I am really trying to implement a DSL (its about music). I
just wasn't aware of that until someone mentioned DLSs here.
The "symbols" problem is one problem I could not come up with anything
delightful (the other one is getting rid of parenthesis).

  
>> (5) Here is something I came up with myself:
>> 
>> def symbols(aDict):
>>     aDict["foo"] = "bar"
>> 
>> def someFunction(aFoo):
>>     print aFoo
>> 
>> symbols(locals())
>> someFunction (foo) #Eh voila: foo is magically defined
>> prints: bar
>> 
>> The call to symbols(locals()) is the "magic, magic" I supected would
>> be required in my original posting. If someFunction was a member of a
>> class, the symbols would be properly tied to that class (albeit not
>> the individual function), but still good enough.
> 
> 
> I disagree about it being "proper" to tie such public symbols to the
> class. But in any case, what you're trying to do is not supported by
> Python. If it works, that's a happy accident.
> 
> "The contents of this dictionary should not be modified; changes may
> not affect the values of local and free variables used by the
> interpreter."

Two posters stronly discouraged that solution. And even with a decorator
it does not look all that beautiful. I'll abandon this one.





More information about the Python-list mailing list