4

this may seem a little odd, but it would make for a convenient way for me to finish a bit of code.

Because Python methods are objects themselves, could a method have a method of its own? That is, if I wanted to do the following (ignoring syntax):

def methodCaller(someArgs, methodB):
    # some stuff here . . .
    variableWithAGoodName = methodB()
    jonSkeet = methodB.methodC(variableWithAGoodName)
    return jonSkeet

Would it be possible? My guess is no, but if methods are just objects, shouldn't it be possible somehow?

Thank you so much!

EDIT: I think as has been posted, I am looking for a high-order function.

My question is somewhat academic as I know I could reorganize my code to do this manner of thing totally differently. But, as it is, I am experimenting with Python to learn at least its basics. I haven't tried this yet, but as I am unfamiliar with Python, it might be possible, just not with this syntax.

Another EDIT: I attempted to be funny with my naming but it made the question unclear. For that I apologize. Here is a better example:

def MethodA(MethodB):
    # MethodB is passed as a parameter but is also a method.
    # MethodB has a method of its own, somehow, because it is technically still
    # an object.
    MethodB.MethodC() #Let's pretend it returns nothing here.
    # Can this happen?
5
  • 1
    It's not at all clear what you are trying to achieve. Probably your goal could be achieved by other means, but you have to tell us what it is. Commented Feb 17, 2012 at 19:54
  • have you tried that? did it give you any error? Commented Feb 17, 2012 at 19:56
  • If methodB() were to return objects of different but interface-compatible classes depending on circumstances, your syntax would be fine (with minor modifications). So if B returns a classD instance, you end up calling classD.methodC() in that case, and classE.methodC() if the returned object was a classE instance. This is a fundamental concept of object-oriented programming, so I guess you are getting at something else here, but what? Commented Feb 17, 2012 at 20:01
  • @F.C. I seem to be able to compile by nesting method definitions. Do I now have to use special syntax to use it? Commented Feb 17, 2012 at 20:15
  • 2
    @BlackVegetable: If I recall correctly, nested functions only come into existence when their parent function is called - the nested function's def is only run through when the parent function is called. So you can't call them from outside the parent function, unless you return the nested function as the return value from the parent function. (see: closures.) This doesn't really do what you want above, though. Commented Feb 17, 2012 at 20:30

2 Answers 2

6

Functions in python are first-class objects with methods and attributes.

def foo():
    print("foo")

def bar():
    print("bar")

foo.bar = bar
foo.bar()                  #outputs "bar"

foo.baz = "Hello, world!"
print(foo.baz)             # outputs "Hello, World!"

Edit:

Because functions are first-class objects, you can also pass them around like any other variable. You can also write "higher-order functions", which are functions of functions (or functions that return functions.)

Edit 2:

[To the tune of 'There ain't no party like an S-Club party!'] There ain't no example like a full-code example!

def higher_order_function (input_function):
    input_function.method()

def input_function_1 ():
    print ("exec'ing input_function_1()")

def input_function_1_method ():
    print ("exec'ing input_function_1_method()")

input_function_1.method = input_function_1_method

higher_order_function(input_function_1)
# prints "exec'ing input_function_1_method"
Sign up to request clarification or add additional context in comments.

9 Comments

In your example, bar isn't really an instance method, it's just a function that also happens to be an attribute of another function object.
@Wooble: what's the distinction? Educate me. ;)
A method is a descriptor, for one, while a function is simply an attribute.
@MattLuongo: Are you saying that a method has access to the function's other methods and attributes (via self) while an attribute does not?
A method has __get__ and __set__ methods iteself, and is of type types.MethodType.
|
4

Yes and no. Obviously they can have attributes assigned to them which work similarly to methods. Further, functions come with methods already attached- for example, the __call__ method, which is called with the function.

However, to add a method to an object, what would you typically do? Subclass the object's class, and add the method. However, if you try to subclass function

imports types
class F(types.FunctionType):
    pass

you'll get this error

type 'function' is not an acceptable base type

If you want to make a "callable" object, that can have methods and use inheritance, try something like this.

class MyCallable(object):
    def __init__(self):
        self.message = "Look ma, I got called!"

    def __call__(self, *args, **kwargs):
        self.print_message()

    def print_message(self):
        print(self.message)


class CallableChild(object):
    def __call__(self, *args, **kwargs):
        super(CallableChild, self).__call__(*args, **kwargs)
        print "...as a child, too!"

7 Comments

Interesting; is there then any way to nest "def" declarations that will be visible outside of the encasing method?
@BlackVegetable not just using 'def' declarations. The funny thing about function attributes is that they aren't accessible from within the function, they can only be set/accessed internally. However, you can definitely pull this off with the callable approach above.
So you've effectively made an object that masquerades as a function by implementing __call__()? (Python's duck typing in action: "it has a __call__ method, looks like a function to me!)
@BlackVegetable though your last edit example is possible, you won't be the one writing MethodC, it could only be a built-in method of types.MethodType or an attribute. Clearly you can emulate this easily, though, with general callables.
Indeed, the built-in function callable() just checks to see whether the object has a __call__() method. Note that classes are callable, since you call them to instantiate them! (Their __call__() method calls __new__() and then __init__().)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.