python class visibility inside nested class [duplicate] - python

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.

Related

How to call a parent class's function? [duplicate]

This question already has answers here:
How do I call a parent class's method from a child class in Python?
(16 answers)
Closed 1 year ago.
I have a parent class with a function. There is a subclass of the parent class that has the same function name, but instead of overriding it as usual, I would like to call the parent's function as well.
Here is an example:
class Person:
def __init__(self,p):
self.p = p
def printp(self):
print(self.p)
class Bob(Person):
def printp(self):
print('letter')
b = Bob('p')
b.printp()
Currently, this prints 'p'. I would like it to print:
p
letter
This could be one solution:
class Person:
def __init__(self,p):
self.p = p
def printp(self):
print(self.p)
class Bob(Person):
def printp(self):
# here I use super to call parent class printp()
super().printp()
print('letter')
b = Bob('p')
b.printp()
Output:
p
letter
You can call the parent's method from the child's method like so:
class Bob(Person):
def printp(self):
super().printp()
print('letter')

Does order of class bases in python matter? [duplicate]

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.

python - specify type with multiple bases (typing AND operator) [duplicate]

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())

Python 3.7 static dictionary of class instances [duplicate]

This question already has answers here:
How do I type hint a method with the type of the enclosing class?
(7 answers)
Closed 2 years ago.
I am reusing a popular c++ idiom where a class contains a static dictionary of class instances:
class Zzz:
elements = {}
def __init__(self, name):
self._name = name
Zzz.elements[name] = self
#staticmethod
def list_instances():
for k in Zzz.elements.items():
print(k)
It worked fine until I added type annotation, now python complains that Zzz is an unknown type: NameError: name 'Zzz' is not defined
from typing import Dict
class Zzz:
elements: Dict[str,Zzz] = {} <---- here
You can forward-reference your type defining it as a string instead.
from typing import Dict
class Zzz:
elements: Dict[str, 'Zzz']
Edit by the way, you can easily auto-populate this static dictionary implementing a __init_subclass__() method.
class Zzz:
elements: Dict[str, 'Zzz'] = {}
name: str
def __init_subclass__(cls, **kw):
cls.elements[cls.name] = cls
class ZzzImpl(Zzz):
name = 'foo'
assert Zzz.elements['foo'] is ZzzImpl
At the time the annotation is "read", Zzz does not yet exist. Python 3.7 still evaluates the annotations at definition time; at which in this case it is still undefined.
This is covered by Pep563:
from __futures__ import annotations

Can we overload behavior of class object [duplicate]

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.

Categories

Resources