When Do You Use 'Self' in Python

When do you use 'self' in Python?

Adding an answer because Oskarbi's isn't explicit.

You use self when:

  1. Defining an instance method. It is passed automatically as the first parameter when you call a method on an instance, and it is the instance on which the method was called.
  2. Referencing a class or instance attribute from inside an instance method. Use it when you want to call a method or access a name (variable) on the instance the method was called on, from inside that method.

You don't use self when

  1. You call an instance method normally. Using Oskarbi's example, if you do instance = MyClass(), you call MyClass.my_method as instance.my_method(some_var) not as instance.my_method(self, some_var).
  2. You reference a class attribute from outside an instance method but inside the class definition.
  3. You're inside a staticmethod.

These don'ts are just examples of when not to use self. The dos are when you should use it.

What is the purpose of the `self` parameter? Why is it needed?

The reason you need to use self. is because Python does not use special syntax to refer to instance attributes. Python decided to do methods in a way that makes the instance to which the method belongs be passed automatically, but not received automatically: the first parameter of methods is the instance the method is called on. That makes methods entirely the same as functions, and leaves the actual name to use up to you (although self is the convention, and people will generally frown at you when you use something else.) self is not special to the code, it's just another object.

Python could have done something else to distinguish normal names from attributes -- special syntax like Ruby has, or requiring declarations like C++ and Java do, or perhaps something yet more different -- but it didn't. Python's all for making things explicit, making it obvious what's what, and although it doesn't do it entirely everywhere, it does do it for instance attributes. That's why assigning to an instance attribute needs to know what instance to assign to, and that's why it needs self..

When to NOT use the self convention in Python?

There are cases where using self is not needed.

Off the top of my head:

  • when the variable is only used in 1 function, or is created inside a function/method and only used in that function/method
  • when the variable doesn't need to be shared between methods
  • when the variable doesn't need to be exposed to other classes/scopes/contexts

Another partial answer is that when creating metaclass/factories/composition something like this might make more sense to move away from the convention of using self like:

class Factory(object):
def __init__(cls, *args, **kwargs):
thing = cls(args, kwargs)

I might be missing some stuff here, but those are what i can think of at the moment.

related:

  • https://stackoverflow.com/a/7722353/2026508
  • What is the purpose of self?

Classes vs Function: Do I need to use 'self' keyword if using a class in Python?

If you develop functions within a Python class you can two ways of defining a function: The one with a self as first parameter and the other one without self.

So, what is the different between the two?

Function with self

The first one is a method, which is able to access content within the created object. This allows you to access the internal state of an individual object, e.g., a counter of some sorts. These are methods you usually use when using object oriented programming. A short intro can be fund here [External Link]. These methods require you to create new instances of the given class.

Function without self

Functions without initialising an instance of the class. This is why you can directly call them on the imported class.

Alternative solution

This is based on the comment of Tom K. Instead of using self, you can also use the decorator @staticmethod to indicate the role of the method within your class. Some more info can be found here [External link].

Final thought

To answer you initial question: You do not need to use self. In your case you do not need self, because you do not share the internal state of an object. Nevertheless, if you are using classes you should think about an object oriented design.

Why do you need explicitly have the self argument in a Python method?

I like to quote Peters' Zen of Python. "Explicit is better than implicit."

In Java and C++, 'this.' can be deduced, except when you have variable names that make it impossible to deduce. So you sometimes need it and sometimes don't.

Python elects to make things like this explicit rather than based on a rule.

Additionally, since nothing is implied or assumed, parts of the implementation are exposed. self.__class__, self.__dict__ and other "internal" structures are available in an obvious way.

Why do I need to use self to reference the class variable in a class method?

I defined 'channel_mapping' as class variable, and why do I need to
use 'self' to refer to it?

You can refer class variable via self (if you ensure it's read-only) and cls inside the class and it's methods and via classes object or instances from outside of the class.

What is the difference between using cls and self? cls is being used in classmethods since they doesn't require initialization and so instance of the object, and self is used inside the methods which do require instances of the object.

I thought I should just use
'channel_mapping'

Scopes inside python doesn't work as in C# for example, where you can call class variable by just writing it's name omitting this where it's redundant. In Python you have to use self to refer to the instance's variable. Same goes to the class variables but with cls (or self) instead.

If you are referencing channel_mapping you are just referencing a variable from the current or a global scopes whether it exists or not and not from the class or it's instance.

or cls.channel_mapping in the 'process' function?

From the class methods you would want for sure to use cls.channel_mapping since cls represents class object. But from the instance's methods, where instead of cls you have self you can refer to the class variable using self.__class__.channel_mapping. What it does is simply returning instance's class which is equal to cls, and calls class variable channel_mapping afterwards.

self.channel_mapping though would return the same result but just because in your code there are no instance attribute called channel_mapping and so python can resolve your reference to the class variable. But if there would be channel_mapping variable inside the instance it won't be any longer related to the original class variables, so in that case you would want to keep channel_mapping read-only.

Summarise, to refer class variable from the class method you would want to just use a cls and to refer class variable from the instance method you better use self.__class__.var construction instead of self.var one.

Also, to define 'channel_mapping' as a class variable like this, or define it as an instance variable in the initializer, is there any thread safety concern in either case?

There are situations when you want to change variables in all instances simultaneously, and that's when class variables comes in handy, you won't need to update every responsible instance variable in every instance, you will just update class variable and that's it.

But speaking of thread safety I'm not really sure will it be simultaneously updated in every thread or not, but self.__class__ will return updated version of a class a soon as it will be updated, so self.__class__ variables will be up to date every time you call it minimizing period within which different threads will use different values of the same variable.

Going up with the initialized variable though, will take longer to update if there are more than one instance so i would consider it less threadsafe.



Related Topics



Leave a reply



Submit