2017-03-27 2 views
1

die auf den folgenden Code aussehen lassen:PyCharm sagen auf gültigen Code "Eigentum kann nicht gelesen werden"

import typing 

def make_getter(field: str) -> typing.Callable[['A'], int]: 
    def getter(self: 'A') -> int: 
     return int(self.dict[field]) 
    return getter 

def make_setter(field: str) -> typing.Callable[['A', int], None]: 
    def setter(self: 'A', value: int): 
     self.dict[field] = str(value) 
    return setter 

class A: 
    def __init__(self, d: dict): 
     super().__init__() 
     self.dict = d 

    get_x = make_getter('foo') 
    set_x = make_setter('foo') 
    x = property(get_x, set_x) 

    def get_y(self) -> int: 
     return int(self.dict['bar']) 
    def set_y(self, value: int): 
     self.dict['bar'] = str(value) 
    y = property(get_y, set_y) 

I 2 definiert Eigenschaften: x und y. Beide sollten ohne Probleme funktionieren, sollten beide das gleiche Verhalten haben. Als nächstes folgenden Code:

a = A(dict()) 
a.x = 10 
print(a.x) 
a.y = 20 
print(a.y) 

PyCharm Editor heißt es: auf a.x "Eigentum kann nicht gelesen werden". Aber dieser Code ist gut ohne Probleme ausgeführt.

Der erste Gedanke war, dass PyCharm fälschlicherweise Typen hergeleitet hat. But look at this short video I recorded. Ich sehe keine Probleme mit den Typen.

auch:

print(repr(a.get_x), repr(a.get_y)) 
print(repr(A.get_x), repr(A.get_y)) 
print(repr(A.x), repr(A.y)) 

Es ist Ausgabe:

<bound method make_getter.<locals>.getter of <__main__.A object at 0x7f7d25145f28>> <bound method A.get_y of <__main__.A object at 0x7f7d25145f28>> 
<function make_getter.<locals>.getter at 0x7f7d25132e18> <function A.get_y at 0x7f7d25132f28> 
<property object at 0x7f7d25143c78> <property object at 0x7f7d25143cc8> 

... so x und y fast gleichwertig.

Warum PyCharm sagt das? Ich habe etwas falsch gemacht oder es ist eine Art Bug? Wie man es repariert (ohne diese Art der Warnung zu deaktivieren)?

Antwort

0

Ich bin mir nicht sicher, warum PyCharm dies erfordert, aber ausdrücklich den Rückgabetyp von __init__ geben machten die Warnungen gehen weg:

def __init__(self, d: dict) -> object:

+0

Das funktioniert, aber ** warum **? Seltsam. Dies macht eine weitere Warnung, weil "__init__" nichts zurückgeben sollte. Technisch sollte es '-> None' sein (was das Problem nicht löst). Vielleicht stoppt Type-Checker nach dem Anzeigen dieser Warnung und prüft die Eigenschaften nicht mehr? – iiNitori

+0

Ich stimme zu, es ist seltsam. Der einzige Grund, warum ich überhaupt darauf stieß, war, dass es einer der vorgeschlagenen Fixes war, die PyCharm aufgeführt hatte. – jknupp

Verwandte Themen