There is no generic way for a function to refer to itself. Consider using a decorator instead. If all you want as you indicated was to print information about the function that can be done easily with a decorator:
from functools import wraps
def showinfo(f):
@wraps(f)
def wrapper(*args, **kwds):
print(f.__name__, f.__hash__)
return f(*args, **kwds)
return wrapper
@showinfo
def aa():
pass
If you really do need to reference the function, then just add it to the function arguments:
def withself(f):
@wraps(f)
def wrapper(*args, **kwds):
return f(f, *args, **kwds)
return wrapper
@withself
def aa(self):
print(self.__name__)
# etc.
Edit to add alternate decorator:
You can also write a simpler (and probably faster) decorator that will make the wrapped function work correctly with Python's introspection:
def bind(f):
"""Decorate function `f` to pass a reference to the function
as the first argument"""
return f.__get__(f, type(f))
@bind
def foo(self, x):
"This is a bound function!"
print(self, x)
>>> foo(42)
<function foo at 0x02A46030> 42
>>> help(foo)
Help on method foo in module __main__:
foo(self, x) method of builtins.function instance
This is a bound function!
This leverages Python's descriptor protocol: functions have a __get__ method that is used to create bound methods. The decorator simply uses the existing method to make the function a bound method of itself. It will only work for standalone functions, if you wanted a method to be able to reference itself you would have to do something more like the original solution.
There is no generic way for a function to refer to itself. Consider using a decorator instead. If all you want as you indicated was to print information about the function that can be done easily with a decorator:
from functools import wraps
def showinfo(f):
@wraps(f)
def wrapper(*args, **kwds):
print(f.__name__, f.__hash__)
return f(*args, **kwds)
return wrapper
@showinfo
def aa():
pass
If you really do need to reference the function, then just add it to the function arguments:
def withself(f):
@wraps(f)
def wrapper(*args, **kwds):
return f(f, *args, **kwds)
return wrapper
@withself
def aa(self):
print(self.__name__)
# etc.
Edit to add alternate decorator:
You can also write a simpler (and probably faster) decorator that will make the wrapped function work correctly with Python's introspection:
def bind(f):
"""Decorate function `f` to pass a reference to the function
as the first argument"""
return f.__get__(f, type(f))
@bind
def foo(self, x):
"This is a bound function!"
print(self, x)
>>> foo(42)
<function foo at 0x02A46030> 42
>>> help(foo)
Help on method foo in module __main__:
foo(self, x) method of builtins.function instance
This is a bound function!
This leverages Python's descriptor protocol: functions have a __get__ method that is used to create bound methods. The decorator simply uses the existing method to make the function a bound method of itself. It will only work for standalone functions, if you wanted a method to be able to reference itself you would have to do something more like the original solution.
http://docs.python.org/library/inspect.html looks promising:
import inspect
def foo():
felf = globals()[inspect.getframeinfo(inspect.currentframe()).function]
print felf.__name__, felf.__doc__
you can also use the sys module to get the name of the current function:
import sys
def bar():
felf = globals()[sys._getframe().f_code.co_name]
print felf.__name__, felf.__doc__
[Python] Can functions be self-referential?
Self referential value
How does “self” in a class work?
object oriented - Why do you need "self." in Python to refer to instance variables? - Software Engineering Stack Exchange
Example:
def function(x):
stuff that works on x and produces y
if condition:
function(y)My code goes through a bunch of calculations for an item and then does those same calculations for the ingredients needed to make that item. And on and on down the chain until it reaches the base ingredients which have no recipe and won't call the function again.
Edit: Oh and by the way, I don't know if "self-referential" means something else in the coding world. I just made that term up. So I'm sorry if there's any confusion.
You have to add “self” as an argument to a class method. Why this specific syntax and how does it get interpreted? Is this because it inherits from the Python object model?
Is there any language where public methods do not contain “self” as an argument?
Thank you
1) Why is self required as an explicit parameter in method signatures?
Because methods are functions and foo.bar(baz) is just syntactic sugar for bar(foo, baz). Classes are just dictionaries where some of the values are functions. (Constructors are also just functions, which is why Python doesn't need new) You can say that Python makes it explicit that objects are built from simpler components. This is in accordance with the "explicit is better than implicit"-philosophy.
In contrast, in Java objects really are magic and cannot be reduced to simpler components in the language. In Java (at least until Java 8) a function is always a method owned by an object, and this ownership cannot be changed due to the static nature of the language. Therefore there is no ambiguity about what this refers to, so it makes sense to have it implicitly defined.
JavaScript is an example of a language that has an implicit this like Java, but where functions can exist separately from objects like in Python. This leads to a lot of confusion about what this refers to when functions are passed around and called in different contexts. Many instinctively think this must refer to some intrinsic property of the function, while it is actually purely determined by the way the function is called. I believe having this as an explicit parameter like in Python would make this much less confusing.
Some other benefits of the explicit self-parameter:
Decorators are just functions which wrap other functions. Since methods are just functions, decorators work just as fine on methods. If there were some kind of implicit self, decorators would not work transparently on methods.
Classmethods and static methods do not take an instance parameter. Classmethods take a class as the first argument (typically called
cls). The explicitselforclsparameters make it much clearer what is going on, and what you have access to in the method.
2) Why must instance variables always be qualified with"self.?
In Java, you don't need to prefix member variables with "this.", but in Python "self." is always required. The reason is that Python does not have an explicit syntax for declaring variables, so there would be no way to tell if x = 7 is supposed to declare a new local variable or assign to a member variable. Specifying self. solves this ambiguity.
There is a rather simple reason that AFAIK hasn't really been touched upon in the cross-site duplicate, nor here: Python started out as a procedural language. It was based on ABC, also a procedural language.
Object-Orientation was added later, and when it was added, Guido van Rossum wanted to add the minimal amount of features possible, in order to keep the design of Python simple. Python already had dicts and functions, so why add something entirely new to the language, when an object can simply be a dict of slots and a class can simply be a dict of functions? A method can be interpreted as a partially-applied function that closes over a single distinguished argument. And that's precisely how methods are implemented in Python: they aren't. They are just functions which receive an extra distinguished argument.
The problem is that you assigned myFoo to an unbound function and are calling it as though it were bound. If you want to be able to use self.myFoo() you will need to curry the object into the first arg yourself.
from functools import partial
def foo(self):
print(self.toString())
class Node:
def __init__(self, myFoo):
self.myFoo = partial(myFoo, self)
def run(self):
self.myFoo()
def toString(self):
return "Hello World"
n = Node(foo)
n.run()
Alternatively you could use
self.myFoo = types.MethodType(myFoo, self)
in your __init__(self, myFoo) method, but using partial is more commonly done, and more versatile since you can use it to curry arguments for any sort of function, not just methods.
This thread looks like what you are looking for. To bound a method to an object (but not its class) at runtime you can do:
import types
n.foo = types.MethodType(foo, n)
Ik this is a basic question but I'm just learning to code and I'm learning about classes. For whatever reason I cannot understand or grasp the use of the self variable in fictions of classes. Hopefully someone's explanation here will help me...