Strategia nadążania za zmianami języka (Python)

16

Pisanie kodu, który będzie działał za lata

Zmieniają się języki programowania. Biblioteki się zmieniają. Niektóre kody sprzed 5, 10, a nawet 20 lat temu mogą nadal działać i dawać oczekiwane wyniki, podczas gdy niektóre kody sprzed 2 lat mogą zawieść z błędem składni. Jest to częściowo nieuniknione, ponieważ języki ewoluują (przynajmniej większość tak robi). Programiści mają obowiązek utrzymywania swojego kodu. Czasami jednak stabilność jest ważnym wymogiem w kodzie produkcyjnym, a kod powinien po prostu działać przez 10 lat, bez potrzeby przeszukiwania kodu przez każdego roku w celu dostosowania go do zmian języka. Mogę też mieć małe skrypty, na przykład do analizy danych naukowych, do których muszę wrócić po nie dotykaniu ich przez lata. Na przykład w biurach meteorologicznych istnieje wiele działających kodów Fortran, nawet dla części nieistotnych z punktu widzenia prędkości, a stabilność kodu jest jednym z powodów. JA' słyszałem, że strach przed niestabilnością jest jednym z obiektów, które mają przeciwko przejściu na Python (oczywiście poza bezwładnością języka; jest to możliwe tylko w przypadku nowego kodu, który nie zależy od starego kodu). Oczywiście jedną ze strategii stabilnego kodu jest zamrożenie całego systemu operacyjnego. Ale nie zawsze jest to możliwe.

Używam Pythona jak na przykład, ale problem nie ogranicza się w szczególności do Pythona.

Dokumenty dotyczące problemów ze zgodnością w języku Python

W przypadku Pythona istnieje kilka dokumentów przedstawiających zasady dotyczące niezgodnych wstecz zmian.

PEP-5

Według PEP 5 :

Musi istnieć co najmniej roczny okres przejściowy między wydaniem przejściowej wersji Pythona a wydaniem wersji niezgodnej wstecz. Użytkownicy będą mieli co najmniej rok na przetestowanie swoich programów i migrację z przestarzałej konstrukcji na alternatywną.

Osobiście uważam, że jeden rok jest raczej krótki. Oznacza to, że mogę napisać kod, a za półtora roku nie będzie już działać.

PEP 291

PEP 291 zawiera niepełne listy wytycznych dotyczących rzeczy, których należy unikać, aby zachować kompatybilność wsteczną. Jednak dotyczy tylko Pythona 2.x. Ponieważ Python 2.7 jest ostatnim wydaniem z serii 2.x, a Python 2.7 zawiera wyłącznie poprawki błędów, ten PEP ma teraz tylko znaczenie historyczne.

PEP 387

Istnieje również PEP 387 na temat niezgodnych wstecz wersji. PEP 387 to projekt, a nie oficjalna polityka. W czerwcu 2009 r. Zostało to omówione na liście dyskusyjnej Python-ideas . Część dyskusji skupiła się na tym, jak programiści mogą pisać kod odporny na zmiany językowe. W jednym poście wymieniono porady dotyczące tego, czego nie należy robić :

Oprócz tego istnieje kilka zasad, które można wywnioskować, które są prawdopodobnie prawdziwe przez większość czasu: nie wywoływaj rzeczy zaczynając od "_", nie małpuj niczego, nie używaj dynamicznej zamiany klas na obiekty z klas innych niż twoje własne , nie zależą od głębokości hierarchii dziedziczenia (na przykład nie ".__bases__[0].__bases__[0]"), upewnij się, że testy przebiegają bez generowania DeprecationWarnings, pamiętaj o potencjalnych konfliktach przestrzeni nazw, dodając atrybuty do klas dziedziczących z innych bibliotek. Nie sądzę jednak, aby wszystkie te rzeczy były zapisane w jednym miejscu.

Ponadto pojawiły się pewne uwagi na temat „pól minowych” (nowe funkcje mogą ulec zmianie) i „zamrożonych obszarów” (bardzo sprzedawane interfejsy API praktycznie nie ulegają zmianie). Cytując Antoine Pitrou :

Myślę, że „zamrożony obszar” powinien być zdefiniowany raczej pozytywnie (jawne publiczne interfejsy API i wyraźnie gwarantowane zachowanie), a nie negatywnie (wyraźne „pole minowe”). W przeciwnym razie zapomnimy umieścić kilka ważnych rzeczy na polu minowym i ugryziemy się później, gdy będziemy musieli zmienić te rzeczy w sposób niezgodny wstecz.

Wydaje się, że nie ma żadnych wniosków z tego wątku, ale zbliża się do sedna tego, czego szukam. Wątek ma prawie cztery lata, więc być może sytuacja się zmieniła lub poprawiła. Jaki kod prawdopodobnie przetrwa i jaki kod jest bardziej delikatny?

Wytyczne dotyczące przenoszenia

Oprócz dokumentów opisanych powyżej, każda wersja Pythona zawiera wytyczne dotyczące przenoszenia : przenoszenie do Python 3.2 , przenoszenie do Python 3.3 itp.

Przydatna kompatybilność

PEP 3151 wprowadził mnie do koncepcji użytecznej kompatybilności . Moim zdaniem sprowadza się to do idei, że tylko jeśli kod jest starannie napisany, programiści muszą zachować ostrożność, aby zachować zgodność. Tak naprawdę nie definiuje użytecznej kompatybilności , ale myślę, że jest podobny do pomysłów cytowanych w dyskusji PEP 387 powyżej.

Z punktu widzenia programistów

Jako programista wiem, że Python zmieni się w przyszłości i że ludzie - przede wszystkim ja - będą próbowali uruchomić mój kod, może za kilka lat, w wersji Python, która ma jedną, dwie, a może trzy mniejsze wersje. Nie wszystko będzie kompatybilne, a tak naprawdę łatwo jest wymyślić kod, który zawiedzie (kiedyś spotkałem się z kodowaniem if sys.version[:3] != '2.3': print 'Wrong version, exiting'). To, czego szukam, to zestaw wskazówek, co robić, a czego nie robić, aby zwiększyć szanse, że mój kod będzie nadal działał bez zmian w przyszłości.

Czy są jakieś takie wytyczne? Jak napisać kod Pythona, który będzie nadal działał w przyszłości?

Moje pytanie odnosi się zarówno do rdzenia Python, do jego biblioteki standardowej, ale także powszechnie używany dodatek bibliotek, w szczególności numpy, scipy, matplotlib.


EDYCJA : Jak dotąd dwie odpowiedzi dotyczą python2 vs. python3. Nie o to mi chodzi. Wiem o narzędziach do migracji z Python2 do Python3. Moje pytanie dotyczy zmian językowych, które mają nadejść . Możemy zrobić coś lepszego niż kryształowa kula , znajdując bardziej stabilne wytyczne kodowania. Na przykład:

  • import modulejest bardziej przyszłościowy niż from module import *, ponieważ ten ostatni może złamać kod, jeśli modulewyhoduje jedną lub więcej nowych funkcji / klas.

  • Używanie nieudokumentowanych metod może być mniej przyszłościowe niż stosowanie udokumentowanych metod, ponieważ coś nieudokumentowanego może świadczyć o tym, że coś nie jest jeszcze stabilne.

To tego rodzaju praktyczne porady dotyczące kodowania, których szukam. Ponieważ chodzi o teraźniejszość → przyszłość, możemy ograniczyć się do Python3, ponieważ Python2 już się nie zmieni.

gerrit
źródło

Odpowiedzi:

13

Jest to nierozwiązany problem w naszej dziedzinie. Nie ma sposobu, aby mieć pewność, że Twój kod będzie działał w nieskończoność. Nawet jeśli Twój kod był naprawdę doskonały w sensie kompatybilnym z nowszymi wersjami (a jeśli tak, to proszę, pracuj w mojej firmie!;)), Jeśli działa, używa lub jest używany przez inne oprogramowanie, które ma błąd lub zmiany w jakikolwiek sposób Twój kod może nie działać.

Nie mogę więc podać listy rzeczy do zrobienia, jeśli będziesz ich przestrzegać, zagwarantuje sukces. Ale to, co możesz zrobić, to zminimalizować ryzyko przyszłych pęknięć i zminimalizować ich skutki. Bardziej kompetentny Pythonista byłby w stanie udzielić ci porady bardziej specyficznej dla Pythona, więc będę musiał być bardziej ogólny:

  • napisz testy jednostkowe. Nawet do rzeczy, o których wiesz, że ich nie potrzebują.

  • używając popularnych / dobrze zaprojektowanych / stabilnych bibliotek i technologii, unikając niepopularnych (a zatem prawdopodobnie wkrótce nieobsługiwanych)

  • unikaj pisania kodu, który wykorzystuje szczegóły implementacji. Kod interfejsów, a nie implementacje. Kod przeciwko wielu implementacjom tego samego interfejsu. Na przykład uruchom swój kod w CPython, Jython i IronPython i zobacz, co się stanie. To da ci świetną opinię na temat twojego kodu. Może to nie być pomocne dla Python3 - ostatnio słyszałem, że niektóre implementacje były nadal w Python2.

  • napisz prosty, przejrzysty kod, który wyraźnie mówi o swoich założeniach

  • napisz modułowy, składalny kod. Jeśli jakiś kod musi zrobić coś niebezpiecznego (w sensie przyszłościowym), rozdziel go, aby nawet jeśli trzeba go zmienić, reszta kodu nie.

  • mieć specyfikację jakiejś formy. Jest to podobne do punktów na temat testów jednostkowych, jeśli używasz testów jako specyfikacji oraz interfejsów, które mogą być również używane jako specyfikacje. (Mam na myśli interfejs w ogólnym znaczeniu, a nie sens słowa kluczowego Java).

Wykonanie którejkolwiek z tych czynności może / zwiększy ilość pracy, którą musisz wykonać. Myślę, że to ma sens - wiele z tych kwestii można również sformułować w kwestii pisania dobrego kodu, co jest dość trudne (moim zdaniem). Czasami może być konieczne naruszenie niektórych z tych sugestii. Jest to całkowicie do przyjęcia, ale należy pamiętać o kosztach.

To wspaniale, że zespół Pythona myśli o tym i na pewno są o wiele bardziej utalentowani i wykwalifikowani niż kiedykolwiek będę. Mimo to szacuję, że jest gdzieś 100%, że czyjś kod gdzieś przestanie działać tak, jak powinien, po aktualizacji Pythona.


źródło
4

Nazywa się to Zarządzanie konfiguracją. Jeśli system nigdy nie zostanie zmieniony, nie powinien się zepsuć. Więc nie zmieniaj systemu. Martwisz się o nowe wydania Python? Nie aktualizuj. Martwisz się o nowe sterowniki urządzeń? Nie aktualizuj. Martwisz się o łatki dla systemu Windows? ...

Ross Patterson
źródło
0

W przypadku Python 2 -> Python 3 istnieje już biblioteka Python 2to3 (dostarczana z oryginalnym pakietem Python).

Na tej podstawie, wkrótce po wydaniu nowych wersji, powinny istnieć podobne biblioteki, które są dostarczane z każdą nową wersją. Jednak, jak stwierdził Martijn, takie biblioteki będą wydawane tylko dla głównych wersji (jak wersja 3.0), ale nie dla mniejszych wersji (takich jak 3.2). Jednak między wersją 3.0 a 3.2 (lub innymi mniejszymi wersjami) nie powinno być żadnych problemów ze zgodnością, więc konwersja do wersji 3.0 powinna być w porządku.

Radzę też spojrzeć na to pytanie .

Rushy Panchal
źródło
1
Nie, 2to3 pomaga tylko uaktualnić kod w głównej luce wersji; nie ma bibliotek (potrzebnych) do aktualizacji kodu w mniejszych wersjach.
Martijn Pieters,
@MartijnPieters Drobne wersje nie powinny mieć problemów ze zgodnością, ponieważ nie powinno być zbyt dużych zmian. Jeśli występują problemy ze zgodnością i duże zmiany, należy wydać całkowicie nową wersję.
0

Nie mam wiele do dodania, „program dla 2 i używaj 2to3” wydaje się ostatnio być popularnym dodatkiem w Internecie. Jest jednak coś, na co powinieneś spojrzeć:

Nazywa się sześć (strona pypi) . Jest to biblioteka Pythona poświęcona pomocy w pisaniu kodu, który działa zarówno na Pythonie 2, jak i Pythonie 3. Widziałem, że jest on wykorzystywany w wielu projektach podczas przeglądania sieci, ale w tej chwili nazwy mi uciekają.

Aren
źródło
Nie do końca to, o co mi chodzi. Zredagowałem pytanie, mam nadzieję, że teraz jest bardziej jasne, czego szukam.
gerrit