Home > front end >  Python: Inherit typing.Optional arguments
Python: Inherit typing.Optional arguments

Time:08-29

I want to inherit optional arguments to another Python class using typing.Optional, but I can't set this attribute in the child class.

I have two classes The parent class Test and the child class Test_inherit.

In the parent class Test I have defined using typing.Optional a optional argument/method/attribute.

If I am using this optional argument in the parent class everything is fine. But if I am inherit this class to a other Test_inherit I am not able to define this optional argument.

Is there a way to do this?

Thanks in advance.

from typing import Optional
from typing import get_type_hints


class Test:
    
    name: str
    type: str
    units: Optional[str]
    
    
    def __init__(self,name,typ_,**kwargs)-> None:
        self.name = name
        self.type = typ_
        #self.units = None
        type_hints = get_type_hints(self)
        for argname in kwargs:
            #print(argname)
            type_hint = type_hints[argname]
            if hasattr(type_hint, "__args__"):  # For the Optional[...] types
                type_hint = next(t for t in type_hint.__args__
                                 if not isinstance(t, type(None)))
 
            setattr(self, argname, type_hint(kwargs[argname]))

            

class Test_inherit(Test):
    TAG: str
    symbol: Optional[str]
    
    def __init__(self,name,typ_,**kwargs)-> None:
        self.TAG='Test_tag'
        super().__init__(name, typ_, **kwargs)
        
 
test0=Test('hallo','float')   
print(test0.name,test0.type)
test1=Test('hallo','float',units='N')   
print(test1.name,test1.type,test1.units)
test2_0=Test_inherit('hallo','float')
print(test2_0.name,test2_0.type)
test2_1=Test_inherit('hallo','float',symbol='N')
print(test2_1.name,test2_1.type,test2_1.symbol)
test3=Test_inherit('hallo','float',units='N')
print(test3.name,test3.type,test3.units)

CodePudding user response:

In python type hinting, Optional means that the variable/attribute is None or a type.

From the docs:

typing.Optional

Optional type.

Optional[X] is equivalent to X | None (or Union[X, None]).

Note that this is not the same concept as an optional argument, which is one that has a default. An optional argument with a default does not require the Optional qualifier on its type annotation just because it is optional. For example:

def foo(arg: int = 0) -> None:
    ...

On the other hand, if an explicit value of None is allowed, the use of Optional is appropriate, whether the argument is optional or not. For example:

def foo(arg: Optional[int] = None) -> None:
    ...

CodePudding user response:

This seems to work. I have changed this line from

type_hints = get_type_hints(self))

to

type_hints = get_type_hints(type(self))
from typing import Optional
from typing import get_type_hints


class Test:
    
    name: str
    type: str
    units: Optional[str]
    
    
    def __init__(self,name,typ_,**kwargs)-> None:
        self.name = name
        self.type = typ_
        #self.units = None
        type_hints = get_type_hints(type(self))
        for argname in kwargs:
            #print(argname)
            type_hint = type_hints[argname]
            if hasattr(type_hint, "__args__"):  # For the Optional[...] types
                type_hint = next(t for t in type_hint.__args__
                                 if not isinstance(t, type(None)))
 
            setattr(self, argname, type_hint(kwargs[argname]))

            

class Test_inherit(Test):
    TAG: str
    symbol: Optional[str]
    
    def __init__(self,name,typ_,**kwargs)-> None:
        self.TAG='Test_tag'
        super().__init__(name, typ_, **kwargs)
  • Related