简体   繁体   中英

Typing Callable in python to specific methods

I am trying to be very strict with my typing, and I encounter an issue when I want to type a Callable to only a few very specific methods!

I have a class:

class Complex:

    def __add__(self, other):
        return Complex()

    def __sub__(self, other):
        return Complex()

    def __div__(self, other):
        return Complex()

In another file I want to write a method that takes in a Callable, but the argument to the method can ONLY be either the add function or the sub function. That means I want the linter to throw an error if I try to pass in div as a function to test_add_sub()

The code below doesn't seem to work :( The linter nor the compiler complains when I pass in the div function to test_add_sub! Nor can I write Complex.complex_func().

    add_sub_type = Complex.__add__ or Complex.__sub__
    add_sub_type2 = Callable[[Complex.__add__ or Complex.__sub__], None]


    def test_add_sub(complex_func: add_sub_type) -> None:
        print(complex_func)
        Complex.complex_func() <-- 'Class Complex has no complex_func member'

Thank you all very much in advance.

typing can't do that. The static pseudo-type system doesn't allow you to define a type with an arbitrary set of members. (Also, Complex.complex_func() isn't how you'd call complex_func anyway.)

If you really, really want a static, type-based check for this, you could use an enum instead of the methods:

class ComplexAddSub(enum.Enum):
    add = Complex.__add__
    sub = Complex.__sub__

    def __call__(self, left: Complex, right: Complex):
        return self.value(left, right)

def whatever(func: ComplexAddSub):
    func(Complex(), Complex())

whatever(ComplexAddSub.add)

Runtime detection

def test_add_sub(complex_func):
    tester = {Complex.__addr__: False, Complex.__sub__: False}
    if (tester.get(complex_func, True)):
        raise RuntimeError('Invalid argument!')

    #complex_func(some_complex_object, another_complex_object)

Read more about Instance methods here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM