[Tutor] Function assignment (was: Re: Function type?)

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Tue Jun 10 20:35:01 2003


> Thanks, everyone! I think callable() is the way to go. Silly me, not
> thinking to look in the built-in functions. I'm working on an
> interactive fiction system, and I'm wondering how to best handle things
> that are either strings or functions. For example, if you have a item
> with a description, you could either have:
>
> >>> pipe = Item('pipe', name='pipe', adj=['green', 'heavy'])
> >>> pipe.desc = "A heavy green pipe."
>
> OR
>
> >>> pipe = Item('pipe', name='pipe', adj=['green', 'heavy'])
> >>> def pipeDesc ():
>         if self.parent == player:
>              return "A green pipe, heavy in your hands."
>         return "A green pipe on the ground."
> >>> pipe.desc = pipeDesc
>
> That way the examine code could look like:
>
> def get(obj):
>     if callable(obj):
>         return obj()
>     return obj



We can probably unify things a little more by making messages themselves
functions, like this:

###
>>> def makeMsg(m):
...     def f():
...         return m
...     return f
...
>>> m1, m2 = makeMsg("hello"), makeMsg("testing!")
>>> m1
<function f at 0x8159384>
>>> m2
<function f at 0x815a2a4>
>>> m1()
'hello'
>>> m2()
'testing!'
###


The advantage of this is that we can rewrite the pipeDesc() function like
this:


###
    def pipeDesc(self):
        if self.parent == player:
            return makeMsg("A green pipe, heavy in your hands.")
        return makeMsg("A green pipe on the ground.")
###



and the get() function can them assume that all objects are callable:

###
def get(obj):
    return obj()
###

... which is sorta useless, but then, I'm trying to maintain the API.
*grin*





> Which leads me to another question: Is it possible to define a function
> immediately as a variable? Something like:
>
> >>> pipe = Item('pipe', name='pipe', adj=['green', 'heavy'])
> >>> def pipe.desc ():
>         if self.parent == player:
>             ....
> OR
>
> >>> pipe.desc = def ():
>         if self.parent == player:
>             ....
>
> Or is there a cleaner way to do this that I'm not aware of?


Yes, very possible.  The makeMsg() function above is an example of a
function that itself generates function objects.  You might be able to
employ the same function-constructing technique when attaching new
description functions to your objects.  So something like:

    pipe.desc = makeDescriptionMethod(...)

should work; makeDescriptionMethod will look very similar to makeMsg(),
except that it'll need to take in 'self', since it's a method.



Your project sounds extraordinarily dynamic!  *grin* Please show us more
of it when you have the chance; it looks like a lot of fun.


Good luck!