Symbols as parameters?

Roald de Vries rdv at roalddevries.nl
Thu Jan 28 17:01:38 CET 2010


On Jan 22, 2010, at 11:56 AM, Roald de Vries wrote:
> Hi Martin,
>
> On Jan 21, 2010, at 8:43 AM, Martin Drautzburg wrote:
>> Hello all,
>>
>> When passing parameters to a function, you sometimes need a paramter
>> which can only assume certain values, e.g.
>>
>>      def move (direction):
>>              ...
>> If direction can only be "up", "down", "left" or "right", you can  
>> solve
>> this by passing strings, but this is not quite to the point:
>>
>>      - you could pass invalid strings easily
>>      - you need to quote thigs, which is a nuisance
>>      - the parameter IS REALLY NOT A STRING, but a direction
>>
>> Alternatively you could export such symbols, so when you "import *"  
>> you
>> have them available in the caller's namespace. But that forces you
>> to "import *" which pollutes your namespace.
>>
>> What I am really looking for is a way
>>
>>      - to be able to call move(up)
>>      - having the "up" symbol only in the context of the function  
>> call
>>
>> So it should look something like this
>>
>> ... magic, magic ...
>> move(up)
>> ... unmagic, unmagic ...
>> print up
>>
>> This should complain that "up" is not defined during the "print"  
>> call,
>> but not when move() is called. And of course there should be as  
>> little
>> magic as possible.
>>
>> Any way to achieve this?
>
> You could do something like this:
>
> class Move(object):
>   def __call__(self, direction):
>       print(direction)
>       return 0
>
>   def up(self):
>       return self('up')
>
> move = Move()
>
> Now move.up() means move('up'), and you can obviously do similar  
> things for other directions.

Question out of general interest in the language:
If I would want to generate such functions in a for-loop, what would I  
have to do? This doesn't work:

    class Move(object):
       def __call__(self, direction):
           return direction

    move = Move()

    for f in ['up', 'down', 'right', 'left']:
        move.__dict__[f] = lambda: move(f)

... because now 'move.up()' returns 'left' because thats the current  
value of f. Is there a way to 'expand' f in the loop? Or a reason that  
you never should use this?





More information about the Python-list mailing list