Właśnie przeszedłem na Pycharm i bardzo się cieszę z wszystkich ostrzeżeń i wskazówek, które pozwalają mi ulepszyć swój kod. Z wyjątkiem tego, którego nie rozumiem:
This inspection detects shadowing names defined in outer scopes.
Wiem, że złą praktyką jest dostęp do zmiennej z zakresu zewnętrznego, ale jaki jest problem z zaciemnieniem zakresu zewnętrznego?
Oto przykład, w którym Pycharm przekazuje mi komunikat ostrzegawczy:
data = [4, 5, 6]
def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
print data
print_data(data)
python
coding-style
pycharm
Framester
źródło
źródło
Odpowiedzi:
Nie ma nic wielkiego w powyższym fragmencie, ale wyobraź sobie funkcję z kilkoma dodatkowymi argumentami i całkiem kilkoma wierszami kodu. Następnie decydujesz się zmienić nazwę swojego
data
argumentu, ponieważyadda
brakuje jednego z miejsc, w których jest on używany w ciele funkcji ... Terazdata
odnosi się do globalnego i zaczynasz mieć dziwne zachowanie - w którym miałbyś o wiele bardziej oczywiste,NameError
gdybyś tego nie zrobił mają globalną nazwędata
.Pamiętaj również, że w Pythonie wszystko jest obiektem (w tym moduły, klasy i funkcje), więc nie ma odrębnych przestrzeni nazw dla funkcji, modułów lub klas. Innym scenariuszem jest importowanie funkcji
foo
u góry modułu i używanie jej gdzieś w treści funkcji. Następnie dodajesz nowy argument do swojej funkcji i nazywasz go - pech -foo
.Wreszcie, wbudowane funkcje i typy również działają w tej samej przestrzeni nazw i mogą być w ten sam sposób cieniowane.
Nic z tego nie stanowi większego problemu, jeśli masz krótkie funkcje, dobre nazewnictwo i przyzwoity, niezakłócony zasięg, ale cóż, czasami trzeba zachować mniej niż doskonały kod i ostrzeżenie o takich możliwych problemach może pomóc.
źródło
nonlocal
słowa kluczowego, aby wyraźnie wskazać zewnętrzny wynik odsyłający (jak w zamknięciach). Zauważ, że różni się to od cieniowania, ponieważ wyraźnie nie ukrywa zmiennych z zewnątrz.Obecnie najlepiej oceniona i zaakceptowana odpowiedź oraz większość odpowiedzi tutaj nie ma sensu.
Nie ma znaczenia, jak długa jest twoja funkcja ani jak nazywasz swoją zmienną opisowo (aby, mam nadzieję, zminimalizować ryzyko potencjalnej kolizji nazwy).
Fakt, że zmienna lokalna twojej funkcji lub jej parametr mają tę samą nazwę w zasięgu globalnym, jest całkowicie nieistotny. I faktycznie, bez względu na to, jak ostrożnie wybierzesz nazwę zmiennej lokalnej, twoja funkcja nigdy nie będzie w stanie przewidzieć „czy moja fajna nazwa
yadda
będzie również używana w przyszłości jako zmienna globalna?”. Rozwiązanie? Po prostu nie przejmuj się tym! Prawidłowym sposobem myślenia jest zaprojektowanie funkcji tak, aby pobierała dane wejściowe tylko z parametrów w sygnaturze sposobem , w ten sposób nie musisz dbać o to, co jest (lub będzie) w zasięgu globalnym, a wtedy cieniowanie w ogóle nie będzie problemem.Innymi słowy, problem zacienienia ma znaczenie tylko wtedy, gdy twoja funkcja musi używać tej samej nazwy zmiennej lokalnej ORAZ zmiennej globalnej. Ale przede wszystkim należy unikać takiego projektu. Kod OP nie ma tak naprawdę problemu projektowego. Po prostu PyCharm nie jest wystarczająco inteligentny i na wszelki wypadek wydaje ostrzeżenie. Tak więc, aby uszczęśliwić PyCharm, a także oczyścić nasz kod, zobacz to rozwiązanie cytowane z odpowiedzi Silyevska, aby całkowicie usunąć zmienną globalną.
Jest to właściwy sposób na „rozwiązanie” tego problemu poprzez naprawienie / usunięcie globalnej rzeczy, a nie dostosowanie bieżącej funkcji lokalnej.
źródło
print_data
JEST zmienną globalną. Pomyśl o tym ...Dobrym rozwiązaniem w niektórych przypadkach może być przeniesienie kodu vars + do innej funkcji:
źródło
To zależy od długości tej funkcji. Im dłuższa funkcja, tym większa szansa, że ktoś ją zmodyfikuje w przyszłości,
data
myśląc, że oznacza to globalny. W rzeczywistości oznacza to lokalny, ale ponieważ funkcja jest tak długa, nie jest dla nich oczywiste, że istnieje lokalny o tej nazwie.W przypadku twojej przykładowej funkcji myślę, że cieniowanie globalnego wcale nie jest złe.
źródło
Zrób to:
źródło
źródło
data
, wszystkie w obrębie kilkuset wierszy kodu?data
to lokalna nazwa w tej funkcji, więc nawet nie sprawdzając / pamiętając czy globalna o tej samej nazwie istnieje , nie mówiąc już, co on zawiera.False
- jeśli nie definiują, ale po prostu spróbować użyćdata
, to patrzy się przez zakresy, aż znajdzie jeden, więc nie znaleźć globalnydata
.data = [1, 2, 3]; def foo(): print(data); foo()
Lubię widzieć zielony haczyk w prawym górnym rogu w pycharm. Dołączam nazwy zmiennych podkreśleniem, aby wyczyścić to ostrzeżenie, dzięki czemu mogę skupić się na ważnych ostrzeżeniach.
źródło
Wygląda na to, że jest to 100% wzorcowy kod zapytania
widzieć:
https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
Miałem ten sam problem, dlatego znalazłem ten post;)
I to ostrzeże
This inspection detects shadowing names defined in outer scopes.
Aby to naprawić, po prostu przenieś
twitter
urządzenie do./tests/conftest.py
I usuń
twitter
urządzenie jak w./tests/test_twitter2.py
To sprawi radość QA, Pycharm i wszystkim
źródło