Assigning remote to self in __init__ means that instance.remote detected first when you access it through self (in the absence of descriptors). To get both options, use either self or type(self) , that is, either from an instance or from a class:
def print_remote(self): print(type(self).remote)
type(self).remote is essentially equivalent to self.__class__.remote , but in general, you should avoid capturing dunder names ( __*__ ) when there is a built-in that does this for you ( type in this case) sub>
They live in different dictionaries and are different variables. self.remote lives in the dict instance, and class.remote in the dict class.
>>> Foo().__dict__['remote'] True >>> Foo.__dict__['remote'] False
When you access through cls using classmethod (or type(self) in a regular method), you will get the first class, when you access through self , you will get an instance.
source share