pylint giving not-callable error for object proper

2019-07-25 15:40发布

问题:

Not sure if I am doing something wrong or if this is a problem with pylint. In the code below I get a linting error that self.type is not callable E1102.

Although I could just ignore it and keep working, seems like this kind of thing should be easy to fix... just can't figure out how to fix it.

from typing import Callable


class Thing:
    def __init__(self, thing_type: Callable):
        self._type = thing_type
        self._value = None

    @property
    def type(self) -> Callable:
        return self._type

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = self.type(value)

回答1:

Will leave this answer unaccepted for awhile, but I did figure out that it has something to do with the use of the @property decorator. In the process of creating the new object property, the type hint information is lost to pylint, and VSCode intellisense doesn't seem to work. Using the old style property syntax I get proper linting and type hinting (see image below)

Seems a bit of a shame, but am hoping someone comes up with a better answer



回答2:

If self._type is a class (instead of an instance), you might want to annotate it with type instead. type is the default metaclass in python.

pylint should handle that better - it knows that you can call a class to create an instance.

class Thing:
    def __init__(self, thing_type: type):
        self._type: type = thing_type
        self._value = None

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = self._type(value)

Note that I also included a variable annotation that requires python 3.6 in there.

Also note that if you do not include a type.setter anywhere, python will conclude on it's own that type cannot be set. If you then refer to _type in your constructor (which you're doing right now), then you already bypass it not being settable.

Edits: I changed the value.setter to use self._type instead. Since it's a private variable to the instance, this is perfectly fine to use. This stops the pylint E1102 from appearing.

Removing the type property will remove E0601. This is because your property is, in the class namespace, shadowing the global variable named type. If it is defined, pylint thinks you intend to use the property(which at that point, is an instance of the property class, instead of a property on a class).