This question already has answers here:
Python super() arguments: why not super(obj)?
(2 answers)
Closed 4 years ago.
I have code snipped like :
class A:
def test(self):
return 'A'
class B(A):
def test(self):
return 'B->' + super(B, self).test()
print(B().test())
Output : B->A
If I write something like this then I'm getting the same output :
class A:
def test(self):
return 'A'
class B(A):
def test(self):
return 'B->' + super().test() # change to super()
print(B().test())
In both cases I'm getting the same output. Then, I want to know what's the difference between this two types of calling of super? What are the pros and cons of using either of them?
In Python 2, only the super(className,self) syntax was possible. Since It was the most used version, as of Python 3 providing no arguments will act the same.
There are two typical use cases for super. In a class hierarchy with single inheritance, super can be used to refer to parent classes without naming them explicitly, thus making the code more maintainable
Related
This question already has answers here:
Python Method overriding, does signature matter?
(5 answers)
Closed 2 years ago.
I have this small example with parent/child classes. I know the code will run without problem, but is it a good practice to override a parent's method with a method which has a different signature? PyCharm does not seem to think it is a good idea:
Signature of method 'Daughter.do()' does not match signature of base method in class 'Mother'
For information, calling Parent method do should execute do(self) not do(self, c).
Code example:
class Parent:
def __init__(self):
self._a = "a"
def do(self):
print("Parent: {}".format(self._a))
class Child(Parent):
def __init__(self):
Parent.__init__(self)
self._b = "b"
def do(self, c):
print("Child: {}".format(self._a))
print("Child: {}".format(self._b))
print("Child: {}".format(c))
It is a bad practice. It for example breaks Liskov substitution principle; If you have a function, that expects a Mother instance, and calls do() on it, it will fail when you pass a Daughter to it.
See this example:
def call_do(mother: Mother) -> None:
mother.do()
You should be able to pass an instance of Mother, or an instance of any of its subclasses into call_do.
But if you now do:
daughter = Daughter()
call_do(daughter)
you will get a TypeError.
This question already has answers here:
What is the difference between a function, an unbound method and a bound method?
(6 answers)
Closed 2 years ago.
I am switching from MATLAB to Python and numpy and I would like to know if there is any difference between the option to define a class method and the option to the function to a class field (instance variable)? Here is the example:
class MyClass:
def __init__(self, a):
self.a=a #some variable
def add(self,b):
return self.a+b
vs
class MyClass:
def __init__(self, a):
self.a=a #some variable
self.add = lambda b: self.a+b
It works in both cases when I call
my_object=MyClass(2)
print(my_object.add(2)) #prints 4
Are there any differences between these two approaches? Any best practices/downsides?
To me, the first one feels more "proper OOP", but the second one feels more flexible. Or, maybe, the definitions are identical, because of the way Python works under the hood?
The second one can't be overridden and takes a lot more space, because there's a separate function in every instance's __dict__ instead of one function in the class __dict__. (Instance method objects are created and reclaimed on the fly if you do it the normal way, or optimized out entirely in many cases depending on Python version.)
This question already has answers here:
Why won't dynamically adding a `__call__` method to an instance work?
(2 answers)
Closed 4 years ago.
I have a wrapper class similar to this (strongly simplified) example:
class wrap(object):
def __init__(self):
self._data = range(10)
def __getitem__(self, key):
return self._data.__getitem__(key)
I can use it like this:
w = wrap()
print w[2] # yields "2"
I thought I could optimize and get rid of one function call by changing to this:
class wrap(object):
def __init__(self):
self._data = range(10)
self.__getitem__ = self._data.__getitem__
However, I receive a
TypeError: 'wrap' object does not support indexing
for the print w[2] line with the latter version.
The direct call to the method, i.e., print w.__getitem__(2), works in both cases...
Why does the assignment version not allow indexing?
EDIT: Regarding the "closed for duplication"
I agree that the linked question has the same answer. It is, however, not at all clear that they are the same question. In particular, someone who does not know the answer here, also does not know that there is an overarching "type of problem" at work. Thus, it won't be clear that they find the answer in a seemingly unrelated question about __call__.
Special methods (essentially anything with two underscores on each end) have to be defined on the class. The internal lookup procedure for special methods completely skips the instance dict. Among other things, this is so if you do
class Foo(object):
def __repr__(self):
return 'Foo()'
the __repr__ method you defined is only used for instances of Foo, and not for repr(Foo).
This question already has answers here:
What do __init__ and self do in Python? [duplicate]
(18 answers)
Closed 6 years ago.
I am learning oop in python so i am having some problem to understand sefl keyword properly.
Suppose a program :
class ge:
def __init__(self,a,b):
self.p=a
self.l=b
def ff(self):
aaa=self.p+self.l
print(aaa)
hh=ge(1,2)
hh.ff()
I am confuse why its necessary to use any string with self with dot ? what it means ? Like:
self.a=a and we can change self.a to ay string like self.b , self.c what it means ?? why its necessary ?
My second question is :
what is difference between defining class with parameter and without parameter ?
class hello(object):
def __init__(self,a,v):
self.a=a
self.v=v
def p(self):
f=self.a+self.v
print(f)
he=hello(1,2)
he.p()
if i defined
class hello(object) its working but
if i defined class like:
class hello(): its also working
but if i defined like:
class hello: its also working
what is the difference class hello(object): , class hello(), class hello:
First question : Duplicate of this question
Second question : There is no difference between the different notations. When you use the parenthesis it means that your class inherits from the class between parenthesis.
In python 3, by default every class inherits from the class object. So hello(object): , class hello():, class hello: are totally equivalent.
In python 2 however, you must explicit the inheritance.
Here are more details on how to create classes in python.
self is used to reference the instance of the class, is like this in Java
Duplicated:
When do you use 'self' in Python?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between #staticmethod and #classmethod in Python?
I am learning OOP in python and came to know about these two methods
It seems that the difference in terms of syntax is that class methods are implicitly passed the class they belong to as their first parameter
class Circle:
all_circles = [] # class variable
#staticmethod
def total_area():
for c in Circle.all_circles: # hardcode class name
# do somethig
#classmethod
def total_area(cls):
for c in cls.all_circles: # no hardcode class name
# do something
I see class method as more flexible since we don't hardcode the class
Question:
- Is it even a question which one is better? #staticmethod or #classmethod?
- what are the scenarios suitable to use of each one of these methods?
A classmethod gets passed the class 'cls' that it was called upon. For more details see: What is the difference between #staticmethod and #classmethod in Python?