This question already has answers here:
When is "self" required?
(3 answers)
Closed 8 years ago.
In methods when is it necessary to use notation like self.variable_name? For instance, I know that in the constructor method it needs to be like
class A(object):
def __init__(self, name):
self.name = name
in order to give it an instance variable. However, what about in other methods? When do I need to put self in front of a variable name and when is it okay to just use a variable name?
You must always put a self as the first argument of an instance method. This is what you use to access the instance variables.
It is similar to this in other languages, but different in that it is required whereas other languages will often have instance variables in scope.
Whenever you are wanting to access attributes of the particular object of type A. For example:
def get_name(self): # here, whenever this method is called, it expects 'self'.
return self.name
When calling this method outside of the class scope, python has self passed implicitly.
example = A('d_rez')
example.get_name() # no arguments are passed, but self is passed implicitly to
# have access to all its attributes!
So to answer your question: You need to pass self whenever you define a method inside a class, and this is usually because there are some attributes involved. Otherwise, it could just be a static function defined outside the class if it doesn't pertain to a particular instance of class A.
Related
This question already has answers here:
What's the difference between a method and a function?
(41 answers)
Closed last year.
Below is a simple class, which is having one method/function in it
class Test():
def f(self):
return "function or method"
What should I call f() here - a method or a function?
From python official document's glossary:
method
A function which is defined inside a class body. If called as an attribute of an instance of that class, the method will get the instance object as its first argument (which is usually called self). See function and nested scope.
I'd say that is a method, since it is associated with the object of the class that it belongs to. I extracted the information from here.
This question already has answers here:
How to pass a default argument value of an instance member to a method?
(6 answers)
Closed 3 years ago.
Say I initialize the following class and attempt to call a method like so:
class tester():
def __init__(self, test):
self.test=test
def caller(self, test=test):
return test
t=tester(6)
t.caller()
#error
I'm hoping that the default arg for the parameter 'test' in the method 'caller' will be the self.test of the instance. Instead I get an error that 'test' is not defined. If I replace test=test with test=self.test I get an error that 'self' is not defined.
Setting the variable directly for the class as follows doesn't result in an error, but of course just simply returns the 'test' from the class, not from the instance:
class tester():
test=1
def __init__(self, test):
self.test=test
def caller(self, test=test):
return test
t=tester(6)
t.caller()
#returns 1
How do I specifically use the instance self.test as a default arg for the method? The reason I want to do this is because I'll be creating a lot of functions that will share many identical parameters that are consistent with each instance of the class. Rather than passing these arguments directly, the method parameters can default to the default values of the instance.
The reason I don't want to simply access the instance variables inside caller directly, but rather rely on a default method argument, is because sometimes I would like to have the option of calling these functions with different values.
The default argument value is evaluated at the time of the class definition, so it is not possible to define a default per-instance. The method object is created, with a single default value, at the time of class definition.
The typical way to achieve what you want would be like this:
def caller(self, test=None):
if test is None
test = self.test
...
This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 5 years ago.
How to use "self" keyword regarding variables? It seems that you can set a class variable inside of __init__ constructor by using "self" prefix???
self is just a name used as a convention to refer to the instance on which methods are bound. Bound methods are always called with the instance as first argument, and you can name that variable anything.
By using self in an instance method, we set instance variables and not class ones. Different programming languages provide mechanisms to access the instance some use implicit this objects, some implicitly call all methods on the instance, and Python explicitly uses passes the instance as the first variable.
This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 9 years ago.
I am learning OOP, so my question on the two statements below probably seems very basic to many, but I just want to check in case I am using Python/OO lingo in the wrong way:
- You must explicitly define 'self' as the first parameter in every class method.
- Python's explicit requirement of self as the first parameter of methods defined in classes, makes it so that it's clear to people what the difference between instance and static methods are.
If the statements are correct concerning the 'self' keyword, is it correct of me to infer that, either as a parameter in method definitions or as a prefix to variables; the presence of the word 'self' commonly indicates that a method or variable is static, whereas the absence of the word 'self' usually indicates that the method or variable is an instance method or variable?
The name of the first parameter is not syntactically important. It's self for normal methods by convention, but that's not enforced.
What is syntactically important is how the method is constructed. A method is a normal method and will receive the instance it's called on as its first argument unless converted into a class method or static method by the classmethod or staticmethod built in functions.
A class method receives the class as its first argument, which by convention is named cls. Although because class methods are less common than normal methods, I've seen more deviations from that convention than I have for normal methods. klass is not totally uncommon, and sometimes people are careless and use self out of habit.
A static method does not receive any automatic arguments.
class ExampleClass(object):
def sample_instance_method(self):
# this is a normal instance method
pass
#classmethod
def sample_class_method(cls):
# this is a class method, and will not receive the individual instance if called on one
pass
#staticmethod
def sample_static_method():
# this is a static method, and will not receive either the instance or the class when called
pass
No, its the other way round.
But I can see why the doubt, these statements are confusing: you put self as first argument in instance methods, and you don't put it in static methods.
Note that although there is no need in naming that first parameter self, it is better to follow that convention as it is clearer to the reader.
Also, don't name selfthe first parameter in a static method, it is possible, yes, but you will for sure confuse the reader.
Look at this code:
class MyClass():
# Why does this give me "NameError: name 'self' is not defined":
mySelf = self
# But this does not?
def myFunction(self):
mySelf2 = self
Basically I want a way for a class to refer to itself without needing to name itself specifically, hence I want self to work for the class, not just methods/functions. How can I achieve this?
EDIT: The point of this is that I'm trying to refer to the class name from inside the class itself with something like self.class._name_ so that the class name isn't hardcoded anywhere in the class's code, and thus it's easier to re-use the code.
EDIT 2: From what I've learned from the answers below, what I'm trying to do is impossible. I'll have to find a different way. Mission abandoned.
EDIT 3: Here is specifically what I'm trying to do:
class simpleObject(object):
def __init__(self, request):
self.request = request
#view_defaults(renderer='string')
class Test(simpleObject):
# this line throws an error because of self
myClassName = self.__class__.__name__
#view_config(route_name=myClassName)
def activateTheView(self):
db = self.request.db
foo = 'bar'
return foo
Note that self is not defined at the time when you want the class to refer to itself for the assignment to work. This is because (in addition to being named arbitrarily), self refers to instances and not classes. At the time that the suspect line of code attempts to run, there is as of yet no class for it to refer to. Not that it would refer to the class if there was.
In a method, you can always use type(self). That will get the subclass of MyClass that created the current instance. If you want to hard-code to MyClass, that name will be available in the global scope of the methods. This will allow you to do everything that your example would allow if it actually worked. E.g, you can just do MyClass.some_attribute inside your methods.
You probably want to modify the class attributes after class creation. This can be done with decorators or on an ad-hoc basis. Metaclasses may be a better fit. Without knowing what you actually want to do though, it's impossible to say.
UPDATE:
Here's some code to do what you want. It uses a metaclass AutoViewConfigMeta and a new decorator to mark the methods that you want view_config applied to. I spoofed the view_config decorator. It prints out the class name when it's called though to prove that it has access to it. The metaclass __new__ just loops through the class dictionary and looks for methods that were marked by the auto_view_config decorator. It cleans off the mark and applies the view_config decorator with the appropriate class name.
Here's the code.
# This just spoofs the view_config decorator.
def view_config(route=''):
def dec(f):
def wrapper(*args, **kwargs):
print "route={0}".format(route)
return f(*args, **kwargs)
return wrapper
return dec
# Apply this decorator to methods for which you want to call view_config with
# the class name. It will tag them. The metaclass will apply view_config once it
# has the class name.
def auto_view_config(f):
f.auto_view_config = True
return f
class AutoViewConfigMeta(type):
def __new__(mcls, name, bases, dict_):
#This is called during class creation. _dict is the namespace of the class and
# name is it's name. So the idea is to pull out the methods that need
# view_config applied to them and manually apply them with the class name.
# We'll recognize them because they will have the auto_view_config attribute
# set on them by the `auto_view_config` decorator. Then use type to create
# the class and return it.
for item in dict_:
if hasattr(dict_[item], 'auto_view_config'):
method = dict_[item]
del method.auto_view_config # Clean up after ourselves.
# The next line is the manual form of applying a decorator.
dict_[item] = view_config(route=name)(method)
# Call out to type to actually create the class with the modified dict.
return type.__new__(mcls, name, bases, dict_)
class simpleObject(object):
__metaclass__ = AutoViewConfigMeta
class Test(simpleObject):
#auto_view_config
def activateTheView(self):
foo = 'bar'
print foo
if __name__=='__main__':
t = Test()
t.activateTheView()
Let me know if you have any questions.
Python has an "explict is better than implicit" design philosophy.
Many languages have an implicit pointer or variable in the scope of a method that (e.g. this in C++) that refers to the object through which the method was invoked. Python does not have this. Here, all bound methods will have an extra first argument that is the object through which the method was invoked. You can call it anything you want (self is not a keyword like this in C++). The name self is convention rather than a syntactic rule.
Your method myFunction defines the variable self as a parameter so it works. There's no such variable at the class level so it's erroring out.
So much for the explanation. I'm not aware of a straightforward way for you to do what you want and I've never seen such requirement in Python. Can you detail why you want to do such a thing? Perhaps there's an assumption that you're making which can be handled in another way using Python.
self is just a name, your self in this case is a class variable and not this for the object using which it is called,
self is treated as a normal variable and it is not defined, where as the self in the function comes from the object used for calling.
you want to treat the object reference in self as a class variable which is not possible.
self isn't a keyword, it's just a convention. The methods are attributes of the class object (not the instance), but they receive the instance as their first argument. You could rename the argument to xyzzy if you wanted and it would still work the same way.
But (as should be obvious) you can't refer to a method argument outside the body of the method. Inside a class block but outside of any method, self is undefined. And the concept wouldn't even make sense -- at the time the class block is being evaluated, no instance of the class can possibly exist yet.
Because the name self is explicitly defined as part of the arguments to myFunction. The first argument to a method is the instance that the method was called on; in the class body, there isn't an "instance we're dealing with", because the class body deals with every possible instance of the class (including ones that don't necessarily exist yet) - so, there isn't a particular object that could be called self.
If you want to refer to the class itself, rather than some instance of it, this is spelled self.__class__ (or, for new-style classes in Py2 and all classes in Py3, type(self)) anywhere self exists. If you want to be able to deal with this in situations where self doesn't exist, then you may want to look at class methods which aren't associated with any particular instance, and so take the class itself in place of self. If you really need to do this in the class body (and, you probably don't), you'll just have to call it by name.
You can't refer to the class itself within the class body because the class doesn't exist at the time that the class body is executed. (If the previous sentence is confusing, reading up about metaclasses will either clear this up or make you more confused.)
Within an instance method, you can refer to the class of the instance with self.__class__, but be careful here. This will be the instance's actual class, which through the power of inheritance might not be the class in which the method was defined.
Within a class method, the class is passed in as the first argument, much like instances are the first argument to instance methods:
class MyClass(object):
#classmethod
def foo(cls):
print cls.__name__
MyClass.foo() # Should print "MyClass"
As with instance methods, the actual class might differ due to inheritance.
class OtherClass(MyClass):
pass
OtherClass.foo() # Should print "OtherClass"
If you really need to refer to MyClass within a method of MyClass, you're pretty much going to have to refer to it as MyClass unless you use magic. This sort of magic is more trouble than it is worth.