This question already has answers here:
How does Python's super() work with multiple inheritance?
(18 answers)
Closed 2 years ago.
Is there a (meaningful) difference the two classes below?
class A(Foo, Bar):
...
vs
class B(Bar, Foo):
...
Does order of class bases in python matter?
Yes, it does. Consider the following:
class A:
def foo(self):
print('class A')
class B:
def foo(self):
print('class B')
class C(A, B):
pass
c = C()
c.foo() # class A
Methods are resolved from left-to-right—e.g., in the example, the foo method comes from class A because A comes before B.
Related
This question already has answers here:
Getting parent private or protected values from the child class
(2 answers)
Closed 8 months ago.
I'm trying to call __search from parent class A in child class B but I get the error:
AttributeError: 'B' object has no attribute '_B__search'
This seems to be only happening for methods starting with __. Is there a way to call these class-private methods when doing inheritance?
class A:
def __init__(self, a):
self.a = a
def __search(self):
return self.a
def display(self):
print(self.a)
class B(A):
def display(self):
res = self.__search()
return res
cB = B(2)
cB.display()
Yes, but it's terrible practice.
In Python, a method whose name begins with __ and does not end with it (so magic methods like __add__ are excluded) is obfuscated with the class name. That is,
class A:
def __foo(self):
return 1
is equivalent to
class A:
def _A__foo(self):
return 1
So if you really want to call __search defined on A, you should write
res = self._A__search()
Again, this is bad practice. Methods starting with __ are obfuscated because that's the Python convention for private functions, so they shouldn't be called from outside the class or in subclasses. You mention in the comments that this is a temporary fix, so that's understandable, but I do hope it's not intended to stay this way for very long.
An attribute name beginning with __ is private, and mangled to _classname__attribute. You need to call it by the mangled name.
class B(A):
def display(self):
res = self._A__search()
return res
This question already has an answer here:
python typing module: Mixin
(1 answer)
Closed 2 years ago.
I understand (as explained in this question and the docs) that a type hint of X or Y can be expressed as:
Union[X,Y]
But how does one express a type hint of X and Y? This would be useful when expressing that the object in question must be a subclass of both X and Y.
The following example works as long as all classes that inherit both X and Y are known in advance:
class X: pass
class Y: pass
class A(X,Y): pass
class B(X,Y): pass
def some_function(arg: Union[A,B]):
pass
# do stuff with arg that only depends on inherited members from X and Y
But what if another package which depends on the code above defines:
class C(X,Y): pass
C also will work in some_function by design. I am looking for a better type hint to use instead of Union[X,Y] that includes any possible class that sub-classes both X and Y.
I understand a workaround could be to define:
class XY(X,Y): pass
And then use it as a base class and type hint:
class A(XY): pass
class B(XY): pass
class C(XY): pass
def some_function(arg: XY): pass
But I am not sure if it would be worthwhile to define a new class only for type hint, which doesn't effect runtime anyway.
How do we create a type hint for any class that is a subclass of both X and Y?
Python type hints does not support explicit intersection annotation. But you have at least two workarounds:
You could introduce a mix class, e.g:
class A:
def foo_a(self):
pass
class B:
def foo_b(self):
pass
class Mix(A, B):
pass
def foo(p: Mix) -> None:
p.foo_a()
p.foo_b()
Or use structural subtyping, Protocol, e.g.:
from typing import Protocol
class Supports_ab(Protocol):
def a(self):
pass
def b(self):
pass
class A:
def a(self):
pass
class B:
def b(self):
pass
class Derived(A, B):
pass
class SomeClassAB: # no need superclass
def a(self):
pass
def b(self):
pass
def foo(p: Supports_ab) -> None:
p.a()
p.b()
foo(SomeClassAB())
foo(Derived())
This question already has an answer here:
Python - Inner Class Not Found
(1 answer)
Closed 5 years ago.
If I have a code like this:
from enum import Enum
class MainClass:
class Options(Enum):
OPTION1=1
OPTION2=2
OPTION3=3
class InternalOperation:
def function1(self, o):
if o == Options.OPTION1:
x=0
......
function1= staticmethod(function1)
I am having trouble doing it and do not know if is it possible to make the enum class visible to the second class inside the main class and how.
You need to explicitly specify the outer class MainClass.Options.OPTION1:
from enum import Enum
class MainClass:
class Options(Enum):
OPTION1=1
OPTION2=2
OPTION3=3
class InternalOperation:
def function1(self, o):
if o == MainClass.Options.OPTION1:
x= 0
Don't make it a static method if you use self as the first argument.
This question already has answers here:
Meaning of #classmethod and #staticmethod for beginner [duplicate]
(12 answers)
Closed 6 years ago.
I'm programming a script with Python using instances of FileHandler class but the second overwrites the first even without being assigned to the same variables.
The class:
class FileHandler():
name = None
path = None
#classmethod
def __init__(self,name,path):
self.name=name
self.path=path
#classmethod
def getName(self):
return self.name
#classmethod
def getPath(self):
return self.path
The script:
import fileHandler
origen=fileHandler.FileHandler('a','b')
destino=fileHandler.FileHandler('c','d')
print origen.getName(),origen.getPath()
print destino.getName(),destino.getPath()
The result:
c d
c d
You are using __init__ method as a class method.
Using #classmethod for every method will result in a singleton, that's why the vars overwrite.
This question already has answers here:
What are metaclasses in Python?
(25 answers)
Closed 7 years ago.
I know we can overload behavior of instances of a class, e.g. -
class Sample(object): pass
s = Sample()
print s
<__main__.Sample object at 0x026277D0>
print Sample
<class '__main__.Sample'>
We can change the result of print s:
class Sample(object):
def __str__(self):
return "Instance of Sample"
s = Sample()
print s
Instance of Sample
Can we change the result of print Sample?
You can use a metaclass:
class SampleMeta(type):
def __str__(cls):
return ' I am a Sample class.'
Python 3:
class Sample(metaclass=SampleMeta):
pass
Python 2:
class Sample(object):
__metaclass__ = SampleMeta
Output:
I am a Sample class.
A metaclass is the class of class. Its relationship to a class is analogous to that of a class to an instance. The same classstatement is used. Inheriting form type instead from object makes it a metaclass. By convention self is replaced by cls.