Vad är nytt i Python 2.1

Författare:

A.M. Kuchling

Introduktion

Den här artikeln förklarar de nya funktionerna i Python 2.1. Även om det inte finns så många förändringar i 2.1 som det fanns i Python 2.0, finns det fortfarande några trevliga överraskningar i butiken. 2.1 är den första utgåvan som styrs genom användning av Python Enhancement Proposals, eller PEPs, så de flesta av de stora förändringarna har medföljande PEPs som ger mer fullständig dokumentation och en designgrund för förändringen. Den här artikeln försöker inte dokumentera de nya funktionerna fullständigt, utan ger helt enkelt en översikt över de nya funktionerna för Python-programmerare. Se dokumentationen för Python 2.1, eller den specifika PEP:en, för mer information om någon ny funktion som intresserar dig särskilt.

Ett av Python-utvecklingsteamets senaste mål har varit att påskynda takten för nya utgåvor, med en ny utgåva var 6:e till 9:e månad. 2.1 är den första utgåvan som kommer ut i denna snabbare takt, med den första alfan som kom ut i januari, 3 månader efter att den slutliga versionen av 2.0 släpptes.

Den slutliga versionen av Python 2.1 släpptes den 17 april 2001.

PEP 227: Nästlade scopes

Den största förändringen i Python 2.1 är Pythons scoping-regler. I Python 2.0 finns det vid varje given tidpunkt högst tre namnrymder som används för att leta upp variabelnamn: lokalt, modulnivå och det inbyggda namnrymden. Detta förvånade ofta människor eftersom det inte stämde överens med deras intuitiva förväntningar. Till exempel fungerar inte en nästlad rekursiv funktionsdefinition:

def f():
    ...
    def g(värde):
        ...
        returnera g(värde-1) + 1
    ...

Funktionen g() kommer alltid att ge upphov till ett NameError-undantag, eftersom bindningen av namnet g inte finns i vare sig dess lokala namnrymd eller i namnrymden på modulnivå. Detta är inte mycket av ett problem i praktiken (hur ofta definierar man rekursivt inre funktioner på det här sättet?), men det gjorde det också klumpigare att använda lambda-uttrycket, och det var ett problem i praktiken. I kod som använder lambda kan man ofta hitta lokala variabler som kopieras genom att de skickas som standardvärden för argument.

def find(self, name):
    "Return list of any entries equal to 'name'"
    L = filter(lambda x, name=name: x == name,
               self.list_attribute)
    return L

Läsbarheten hos Python-kod skriven i en starkt funktionell stil blir därför mycket lidande.

Den mest betydande förändringen i Python 2.1 är att statisk scoping har lagts till i språket för att lösa detta problem. Som en första effekt är standardargumentet namn=namn nu onödigt i exemplet ovan. Enkelt uttryckt, när ett givet variabelnamn inte tilldelas ett värde inom en funktion (genom en tilldelning, eller genom def, class, eller import), kommer referenser till variabeln att sökas i det lokala namnrymden i det omslutande scopet. En mer detaljerad förklaring av reglerna, och en dissektion av implementationen, finns i PEP.

Denna ändring kan orsaka vissa kompatibilitetsproblem för kod där samma variabelnamn används både på modulnivå och som en lokal variabel inom en funktion som innehåller ytterligare funktionsdefinitioner. Detta verkar dock ganska osannolikt, eftersom sådan kod skulle ha varit ganska förvirrande att läsa från början.

En bieffekt av ändringen är att satserna from module import * och exec har blivit olagliga inom en funktionsomfång under vissa förhållanden. Python-referensmanualen har alltid sagt att from module import * endast är lagligt på den högsta nivån i en modul, men CPython-tolken har aldrig tidigare tillämpat detta. Som en del av implementeringen av nästlade omfattningar måste kompilatorn som omvandlar Python-källkod till bytecodes generera annan kod för att komma åt variabler i en omgivande omfattning. from module import * och exec gör det omöjligt för kompilatorn att lista ut detta, eftersom de lägger till namn i det lokala namnrymden som är okända vid kompileringstillfället. Om en funktion innehåller funktionsdefinitioner eller lambda-uttryck med fria variabler kommer kompilatorn därför att flagga detta genom att generera ett SyntaxError-undantag.

För att göra den föregående förklaringen lite tydligare, här är ett exempel:

x = 1
def f():
    # Nästa rad är ett syntaxfel
    exekvera 'x=2'
    def g():
        returnera x

Rad 4 som innehåller exec-satsen är ett syntaxfel, eftersom exec skulle definiera en ny lokal variabel med namnet x vars värde ska nås av g().

Detta borde inte vara någon större begränsning, eftersom exec sällan används i den mesta Python-koden (och när det används är det ofta ett tecken på dålig design).

Kompatibilitetsproblem har lett till att nästlade scopes införs gradvis; i Python 2.1 är de inte aktiverade som standard, men kan slås på inom en modul genom att använda en future-sats som beskrivs i PEP 236. (Se följande avsnitt för ytterligare diskussion om PEP 236.) I Python 2.2 kommer nästlade scopes att bli standard och det kommer inte att finnas något sätt att stänga av dem, men användare kommer att ha haft hela 2.1:s livstid för att åtgärda eventuella fel som uppstår till följd av deras införande.

Se även

PEP 227 - Statiskt nästlade scopes

Skriven och implementerad av Jeremy Hylton.

PEP 236: __framtida__ direktiv

Reaktionen på nested scopes var en utbredd oro för farorna med att bryta kod med 2.1-versionen, och den var tillräckligt stark för att få Pythoneers att ta ett mer konservativt tillvägagångssätt. Detta tillvägagångssätt består i att införa en konvention för att aktivera valfri funktionalitet i version N som kommer att bli obligatorisk i version N+1.

Syntaxen använder en from...import-sats med det reserverade modulnamnet __future__. Nested scopes kan aktiveras genom följande uttalande:

from __future__ import nested_scopes

Även om det ser ut som en vanlig import-sats är det inte det; det finns strikta regler för var en sådan framtida sats kan placeras. De kan bara vara högst upp i en modul, och måste föregå all Python-kod eller vanliga import-satser. Detta beror på att sådana uttalanden kan påverka hur Pythons bytecode-kompilator analyserar kod och genererar bytecode, så de måste föregå alla uttalanden som kommer att resultera i att bytecodes produceras.

Se även

PEP 236 - Tillbaka till __framtiden__

Skriven av Tim Peters och huvudsakligen implementerad av Jeremy Hylton.

PEP 207: Rika jämförelser

I tidigare versioner var Pythons stöd för att implementera jämförelser på användardefinierade klasser och tilläggstyper ganska enkelt. Klasser kunde implementera en __cmp__()-metod som fick två instanser av en klass, och kunde bara returnera 0 om de var lika eller +1 eller -1 om de inte var det; metoden kunde inte ge upphov till ett undantag eller returnera något annat än ett booleskt värde. Användare av Numeric Python tyckte ofta att denna modell var för svag och restriktiv, eftersom det i de numeriska program som Numeric Python används för skulle vara mer användbart att kunna utföra elementvisa jämförelser av två matriser och returnera en matris som innehåller resultaten av en given jämförelse för varje element. Om de två matriserna är av olika storlek måste jämförelsen kunna ge upphov till ett undantag för att signalera felet.

I Python 2.1 lades rika jämförelser till för att stödja detta behov. Python-klasser kan nu individuellt överbelasta var och en av operationerna <, <=, >, >=, == och !=. De nya magiska metodnamnen är:

Operation

Metodnamn

<

__lt__()

<=

__le__()

>

__gt__()

>=

__ge__()

==

__eq__()

!=

__ne__()

(De magiska metoderna är uppkallade efter motsvarande Fortran-operatorer .LT.. .LE., &c. Numeriska programmerare är nästan säkert ganska bekanta med dessa namn och kommer att tycka att de är lätta att komma ihåg)

Var och en av dessa magiska metoder är av formen method(self, other), där self är objektet på vänster sida av operatorn, medan other är objektet på höger sida. Till exempel kommer uttrycket A < B att leda till att A.__lt__(B) anropas.

Var och en av dessa magiska metoder kan returnera vad som helst: en boolesk, en matris, en lista eller något annat Python-objekt. Alternativt kan de ge upphov till ett undantag om jämförelsen är omöjlig, inkonsekvent eller på annat sätt meningslös.

Den inbyggda funktionen cmp(A,B) kan använda det rika jämförelsemaskineriet och accepterar nu ett valfritt argument som anger vilken jämförelseoperation som ska användas; detta ges som en av strängarna "<", "<=", ">", ">=", "==" eller "!=". Om den anropas utan det valfria tredje argumentet kommer cmp() bara att returnera -1, 0 eller +1 som i tidigare versioner av Python; annars kommer den att anropa lämplig metod och kan returnera vilket Python-objekt som helst.

Det finns också motsvarande förändringar av intresse för C-programmerare; det finns en ny plats tp_richcmp i typobjekt och ett API för att utföra en given rik jämförelse. Jag kommer inte att täcka C API här, men hänvisar dig till PEP 207, eller till 2.1:s C API-dokumentation, för den fullständiga listan över relaterade funktioner.

Se även

PEP 207 - Jämförelser av rikedomar

Skrivet av Guido van Rossum, starkt baserat på tidigare arbete av David Ascher, och implementerat av Guido van Rossum.

PEP 230: Ramverk för varning

Under sina 10 år har Python samlat på sig ett visst antal föråldrade moduler och funktioner längs vägen. Det är svårt att veta när en funktion är säker att ta bort, eftersom det inte finns något sätt att veta hur mycket kod som använder den — kanske inga program är beroende av funktionen, eller kanske många gör det. För att göra det möjligt att ta bort gamla funktioner på ett mer strukturerat sätt lades ett varningsramverk till. När Python-utvecklarna vill bli av med en funktion utlöses först en varning i nästa version av Python. Den följande Python-versionen kan sedan ta bort funktionen, och användarna har haft en hel versionscykel på sig att ta bort användningen av den gamla funktionen.

Python 2.1 lägger till ett ramverk för varningar som kan användas i detta system. Det lägger till en warnings-modul som tillhandahåller funktioner för att utfärda varningar och för att filtrera bort varningar som du inte vill ska visas. Tredjepartsmoduler kan också använda det här ramverket för att avskriva gamla funktioner som de inte längre vill stödja.

Till exempel, i Python 2.1 är modulen regex föråldrad, så import av den orsakar en varning som skrivs ut:

>>> import regex
__main__:1: DeprecationWarning: the regex module
         is deprecated; please use the re module
>>>

Varningar kan utfärdas genom att anropa funktionen warnings.warn():

warnings.warn("funktion X stöds inte längre")

Den första parametern är varningsmeddelandet; ytterligare valfria parametrar kan användas för att ange en viss varningskategori.

Filter kan läggas till för att inaktivera vissa varningar; ett reguljärt uttrycksmönster kan tillämpas på meddelandet eller på modulnamnet för att undertrycka en varning. Du kanske till exempel har ett program som använder modulen regex och inte vill ta dig tid att konvertera det till att använda modulen re just nu. Varningen kan undertryckas genom att anropa

import varningar
warnings.filterwarnings(åtgärd = 'ignorera',
                        message='.*regex-modulen är föråldrad',
                        kategori=DeprecationWarning,
                        modul = '__main__')

Detta lägger till ett filter som endast gäller för varningar av klassen DeprecationWarning som utlöses i modulen __main__, och tillämpar ett reguljärt uttryck som endast matchar meddelandet om att modulen regex är föråldrad, och gör att sådana varningar ignoreras. Varningar kan också skrivas ut endast en gång, skrivas ut varje gång den felaktiga koden exekveras eller omvandlas till undantag som gör att programmet stoppas (om inte undantagen fångas på vanligt sätt, förstås).

Funktioner har också lagts till i Pythons C API för att utfärda varningar; se PEP 230 eller Pythons API-dokumentation för mer information.

Se även

PEP 5 - Riktlinjer för språkutveckling

Skriven av Paul Prescod, för att specificera procedurer som ska följas när man tar bort gamla funktioner från Python. Policyn som beskrivs i denna PEP har inte officiellt antagits, men den slutliga policyn kommer förmodligen inte att skilja sig alltför mycket från Prescods förslag.

PEP 230 - Varning för ramverk

Skriven och implementerad av Guido van Rossum.

PEP 229: Nybyggt system

När Python kompilerades var användaren tvungen att gå in och redigera filen Modules/Setup för att aktivera olika tilläggsmoduler; standarduppsättningen är relativt liten och begränsad till moduler som kompileras på de flesta Unix-plattformar. Detta innebär att på Unix-plattformar med många fler funktioner, framför allt Linux, innehåller Python-installationer ofta inte alla användbara moduler som de skulle kunna innehålla.

I Python 2.0 tillkom Distutils, en uppsättning moduler för distribution och installation av tillägg. I Python 2.1 används Distutils för att kompilera en stor del av standardbiblioteket med tilläggsmoduler och automatiskt upptäcka vilka som stöds på den aktuella maskinen. Förhoppningen är att detta ska göra Python-installationer enklare och mer funktionsrika.

Istället för att behöva redigera filen Modules/Setup för att aktivera moduler, körs skriptet setup.py i den översta katalogen i Python-källdistributionen vid byggtiden och försöker upptäcka vilka moduler som kan aktiveras genom att undersöka modulerna och header-filerna på systemet. Om en modul är konfigurerad i Modules/Setup, kommer skriptet setup.py inte att försöka kompilera den modulen utan kommer att hänvisa till innehållet i Modules/Setup. Detta ger ett sätt att specificera eventuella konstiga kommandoradsflaggor eller bibliotek som krävs för en viss plattform.

I en annan långtgående förändring av byggmekanismen har Neil Schemenauer omstrukturerat saker så att Python nu använder en enda makefile som inte är rekursiv, istället för makefiles i toppkatalogen och i var och en av underkatalogerna Python/, Parser/, Objects/ och Modules/. Detta gör det snabbare att bygga Python och gör det också tydligare och enklare att hacka Makefiles.

Se även

PEP 229 - Använda Distutils för att bygga Python

Skriven och implementerad av A.M. Kuchling.

PEP 205: Svaga referenser

Svaga referenser, som är tillgängliga via modulen weakref, är en mindre men användbar ny datatyp i Python-programmerarens verktygslåda.

Att lagra en referens till ett objekt (t.ex. i en ordbok eller en lista) har som bieffekt att objektet hålls vid liv för alltid. Det finns några specifika fall där detta beteende inte är önskvärt, objektcacher är det vanligaste, och ett annat är cirkulära referenser i datastrukturer som träd.

Tänk till exempel på en memoiseringsfunktion som cachelagrar resultaten av en annan funktion f(x) genom att lagra funktionens argument och dess resultat i en ordbok:

_cache = {}
def memoize(x):
    if _cache.has_key(x):
        return _cache[x]

    retval = f(x)

    # Cache the returned object
    _cache[x] = retval

    return retval

Den här versionen fungerar för enkla saker som heltal, men den har en bieffekt; _cache-ordlistan innehåller en referens till returvärdena, så de kommer aldrig att avallokeras förrän Python-processen avslutas och rensas upp. Detta är inte särskilt märkbart för heltal, men om f() returnerar ett objekt, eller en datastruktur som tar upp mycket minne, kan detta vara ett problem.

Svaga referenser är ett sätt att implementera en cache som inte håller objekt vid liv längre än vad som är nödvändigt. Om ett objekt endast är tillgängligt via svaga referenser kommer objektet att avallokeras och de svaga referenserna kommer nu att indikera att objektet som det hänvisade till inte längre existerar. En svag referens till ett objekt obj skapas genom att anropa wr = weakref.ref(obj). Objektet som refereras till returneras genom att anropa den svaga referensen som om den vore en funktion: wr(). Den returnerar det refererade objektet, eller None om objektet inte längre existerar.

Detta gör det möjligt att skriva en memoize()-funktion vars cache inte håller objekt vid liv, genom att lagra svaga referenser i cacheminnet.

_cache = {}
def memoize(x):
    if _cache.has_key(x):
        obj = _cache[x]()
        # If weak reference object still exists,
        # return it
        if obj is not None: return obj

    retval = f(x)

    # Cache a weak reference
    _cache[x] = weakref.ref(retval)

    return retval

Modulen weakref gör det också möjligt att skapa proxyobjekt som beter sig som svaga referenser — ett objekt som endast refereras av proxyobjekt avallokeras – men istället för att kräva ett explicit anrop för att hämta objektet, vidarebefordrar proxyn transparent alla operationer till objektet så länge objektet fortfarande existerar. Om objektet är deallokerat kommer försök att använda en proxy att orsaka ett weakref.ReferenceError undantag.

proxy = weakref.proxy(obj)
proxy.attr # Likvärdig med obj.attr
proxy.meth() # Motsvarar obj.meth()
del obj
proxy.attr # ger upphov till weakref.ReferenceError

Se även

PEP 205 - Svaga referenser

Skriven och implementerad av Fred L. Drake, Jr.

PEP 232: Funktionsattribut

I Python 2.1 kan funktioner nu ha godtycklig information kopplad till sig. Folk använde ofta docstrings för att hålla information om funktioner och metoder, eftersom attributet __doc__ var det enda sättet att bifoga någon information till en funktion. I webbapplikationsservern Zope markeras till exempel funktioner som säkra för allmän åtkomst genom att ha en docstring, och i John Aycocks SPARK-ramverk för parsning innehåller docstrings delar av BNF-grammatiken som ska parsas. Denna överbelastning är olycklig, eftersom docstrings egentligen är avsedda att innehålla en funktions dokumentation; till exempel innebär det att du inte kan dokumentera funktioner avsedda för privat användning i Zope på rätt sätt.

Godtyckliga attribut kan nu ställas in och hämtas på funktioner med hjälp av den vanliga Python-syntaxen:

def f(): pass

f.publish = 1
f.secure = 1
f.grammatik = "A ::= B (C D)*"

Dictionariet som innehåller attribut kan nås som funktionens __dict__. Till skillnad från attributet __dict__ för klassinstanser kan du i funktioner faktiskt tilldela en ny ordbok till __dict__, även om det nya värdet är begränsat till en vanlig Python-ordbok; du kan inte vara listig och ställa in den på en UserDict-instans, eller något annat slumpmässigt objekt som beter sig som en mappning.

Se även

PEP 232 - Funktionsattribut

Skriven och implementerad av Barry Warsaw.

PEP 235: Importera moduler på plattformar som inte är skiftlägeskänsliga

Vissa operativsystem har filsystem som är skiftlägesokänsliga, MacOS och Windows är de främsta exemplen; på dessa system är det omöjligt att skilja på filnamnen FILE.PY och file.py, även om de lagrar filnamnet i dess ursprungliga skiftlägesform (de bevarar också skiftlägesformen).

I Python 2.1 kommer import att fungera för att simulera skiftlägeskänslighet på plattformar som inte är skiftlägeskänsliga. Python kommer nu att söka efter den första skiftlägeskänsliga matchningen som standard och ge upphov till ett ImportError om ingen sådan fil hittas, så import file kommer inte att importera en modul med namnet FILE.PY. Matchning utan skiftlägeskänslighet kan begäras genom att ställa in miljövariabeln PYTHONCASEOK innan Python-tolken startas.

PEP 217: Hook för interaktiv display

Vid interaktiv användning av Python-tolken visas kommandon med hjälp av den inbyggda funktionen repr(). I Python 2.1 kan variabeln sys.displayhook() ställas in på ett anropsbart objekt som kommer att anropas istället för repr(). Du kan till exempel ställa in den på en speciell funktion för snygga utskrifter:

>>> # Create a recursive data structure
... L = [1,2,3]
>>> L.append(L)
>>> L # Show Python's default output
[1, 2, 3, [...]]
>>> # Use pprint.pprint() as the display function
... import sys, pprint
>>> sys.displayhook = pprint.pprint
>>> L
[1, 2, 3,  <Recursion on list with id=135143996>]
>>>

Se även

PEP 217 - Display-hook för interaktiv användning

Skrivet och implementerat av Moshe Zadka.

PEP 208: Ny modell för tvångsmedel

Hur numerisk coercion görs på C-nivå ändrades avsevärt. Detta kommer endast att påverka författarna av C-tillägg till Python, vilket ger dem mer flexibilitet när det gäller att skriva tilläggstyper som stöder numeriska operationer.

Tilläggstyper kan nu ställa in typflaggan Py_TPFLAGS_CHECKTYPES i sin PyTypeObject-struktur för att ange att de stöder den nya coercion-modellen. I sådana tilläggstyper kan de numeriska slotfunktionerna inte längre anta att de kommer att få två argument av samma typ; istället kan de få två argument av olika typer och kan då utföra sin egen interna kooperation. Om slot-funktionen får en typ som den inte kan hantera kan den ange att den misslyckats genom att returnera en referens till singleton-värdet Py_NotImplemented. De numeriska funktionerna för den andra typen kommer då att provas, och kanske kan de hantera operationen; om den andra typen också returnerar Py_NotImplemented, kommer ett TypeError att uppstå. Numeriska metoder skrivna i Python kan också returnera Py_NotImplemented, vilket gör att tolken agerar som om metoden inte existerade (kanske ger ett TypeError, kanske provar ett annat objekts numeriska metoder).

Se även

PEP 208 - Omarbetning av tvångsmodellen

Skriven och implementerad av Neil Schemenauer, starkt baserad på tidigare arbete av Marc-André Lemburg. Läs detta för att förstå detaljerna i hur numeriska operationer nu kommer att behandlas på C-nivå.

PEP 241: Metadata i Python-paket

Ett vanligt klagomål från Python-användare är att det inte finns någon enda katalog över alla Python-moduler som finns. T. Middletons Vaults of Parnassus på www.vex.net/parnassus/ (pensionerad i februari 2009, available in the Internet Archive Wayback Machine) var den största katalogen över Python-moduler, men det är frivilligt att registrera programvara på Vaults och många brydde sig inte om det.

Som ett första litet steg mot att lösa problemet kommer Python-programvara som paketeras med Distutils sdist-kommando att inkludera en fil med namnet PKG-INFO som innehåller information om paketet, till exempel dess namn, version och författare (metadata, i katalogiseringsterminologi). PEP 241 innehåller den fullständiga listan över fält som kan finnas i PKG-INFO-filen. När människor börjar paketera sin programvara med Python 2.1 kommer fler och fler paket att innehålla metadata, vilket gör det möjligt att bygga automatiserade katalogiseringssystem och experimentera med dem. Med erfarenhet av resultatet kanske det blir möjligt att utforma en riktigt bra katalog och sedan bygga in stöd för den i Python 2.2. Till exempel skulle Distutils sdist och bdist_* kunna stödja ett upload-alternativ som automatiskt laddar upp ditt paket till en katalogserver.

Du kan börja skapa paket som innehåller PKG-INFO även om du inte använder Python 2.1, eftersom en ny version av Distutils kommer att göras för användare av tidigare Python-versioner. Version 1.0.2 av Distutils innehåller de ändringar som beskrivs i PEP 241, samt diverse buggfixar och förbättringar. Den kommer att finnas tillgänglig från Distutils SIG på https://www.python.org/community/sigs/current/distutils-sig/.

Se även

PEP 241 - Metadata för Python-programvarupaket

Skriven och implementerad av A.M. Kuchling.

PEP 243 - Uppladdningsmekanism för modulförvar

Detta utkast till PEP är skrivet av Sean Reifschneider och beskriver en föreslagen mekanism för att ladda upp Python-paket till en central server.

Nya och förbättrade moduler

  • Ka-Ping Yee bidrog med två nya moduler: inspect.py, en modul för att få information om live Python-kod, och pydoc.py, en modul för att interaktivt konvertera dokumentationssträngar till HTML eller text. Som en bonus använder Tools/scripts/pydoc, som nu installeras automatiskt, pydoc.py för att visa dokumentation med ett Python-modul-, paket- eller klassnamn. Till exempel, pydoc xml.dom visar följande:

    Python Library Documentation: paket xml.dom in xml
    
    NAMN
        xml.dom - Implementering av W3C:s dokumentobjektmodell för Python.
    
    FIL
        /usr/local/lib/python2.1/xml/dom/__init__.pyc
    
    BESKRIVNING
        Python-mappningen av Document Object Model finns dokumenterad i
        Python Library Reference i avsnittet om paketet xml.dom.
    
        Detta paket innehåller följande moduler:
          ...
    

    pydoc innehåller också en Tk-baserad interaktiv hjälpbläddrare. pydoc blir snabbt beroendeframkallande; prova det!

  • Två olika moduler för enhetstestning har lagts till i standardbiblioteket. Modulen doctest, som Tim Peters har bidragit med, tillhandahåller ett testramverk som bygger på att köra inbäddade exempel i dokumentsträngar och jämföra resultaten med den förväntade utdata. PyUnit, som Steve Purcell har bidragit med, är ett ramverk för enhetstestning som inspirerats av JUnit, som i sin tur var en anpassning av Kent Becks testramverk för Smalltalk. Se https://pyunit.sourceforge.net/ för mer information om PyUnit.

  • Modulen difflib innehåller en klass, SequenceMatcher, som jämför två sekvenser och beräknar de ändringar som krävs för att omvandla den ena sekvensen till den andra. Den här modulen kan till exempel användas för att skriva ett verktyg som liknar Unix-programmet diff, och i själva verket visar exempelprogrammet Tools/scripts/ndiff.py hur man skriver ett sådant skript.

  • curses.panel, en omslagslösning för panelbiblioteket, en del av ncurses och av SYSV curses, har skrivits av Thomas Gellekum. Panelbiblioteket ger fönster den extra egenskapen att de är djupa. Fönster kan flyttas högre eller lägre i djupordningen, och panelbiblioteket räknar ut var paneler överlappar varandra och vilka sektioner som är synliga.

  • PyXML-paketet har gått igenom några utgåvor sedan Python 2.0, och Python 2.1 innehåller en uppdaterad version av xml-paketet. Några av de anmärkningsvärda ändringarna inkluderar stöd för Expat 1.2 och senare versioner, möjligheten för Expat-parser att hantera filer i alla kodningar som stöds av Python och olika buggfixar för SAX, DOM och modulen minidom.

  • Ping bidrog också med en annan hook för att hantera undantag som inte fångats upp. sys.excepthook() kan sättas till ett anropbart objekt. När ett undantag inte fångas upp av något tryexcept block, kommer undantaget att skickas till sys.excepthook(), som sedan kan göra vad den vill. På Ninth Python Conference demonstrerade Ping en tillämpning av denna hook: att skriva ut en utökad traceback som inte bara listar stackrutorna utan även funktionsargumenten och de lokala variablerna för varje ruta.

  • Olika funktioner i modulen time, t.ex. asctime() och localtime(), kräver ett argument i form av ett flyttal som innehåller tiden i sekunder sedan epoken. Den vanligaste användningen av dessa funktioner är att arbeta med aktuell tid, så argumentet med flyttal har gjorts valfritt; när ett värde inte anges kommer aktuell tid att användas. Till exempel behöver loggfilsposter vanligtvis en sträng som innehåller aktuell tid; i Python 2.1 kan time.asctime() användas istället för den längre time.asctime(time.localtime(time.time())) som tidigare krävdes.

    Denna ändring föreslogs och genomfördes av Thomas Wouters.

  • Modulen ftplib har nu som standard att hämta filer i passivt läge, eftersom det är mer sannolikt att passivt läge fungerar bakom en brandvägg. Denna begäran kom från Debians buggspårningssystem, eftersom andra Debian-paket använder ftplib för att hämta filer och sedan inte fungerar bakom en brandvägg. Det anses osannolikt att detta kommer att orsaka problem för någon, eftersom Netscape använder passivt läge som standard och få människor klagar, men om passivt läge inte passar för din applikation eller nätverksinställning, anropa set_pasv(0) på FTP-objekt för att inaktivera passivt läge.

  • Stöd för rå socket-åtkomst har lagts till i modulen socket, med bidrag från Grant Edwards.

  • Modulen pstats innehåller nu en enkel interaktiv statistikbläddrare för visning av tidsprofiler för Python-program, som startas när modulen körs som ett skript. Bidrag från Eric S. Raymond.

  • En ny implementationsberoende funktion, sys._getframe([depth]), har lagts till för att returnera ett givet ramobjekt från den aktuella anropsstacken. sys._getframe() returnerar ramen högst upp i anropsstacken; om det valfria heltalsargumentet depth anges, returnerar funktionen den ram som ligger depth anrop under toppen av stacken. Exempel: sys._getframe(1) returnerar anroparens ramobjekt.

    Den här funktionen finns bara i CPython, inte i Jython eller .NET-implementeringen. Använd den för felsökning och motstå frestelsen att lägga in den i produktionskoden.

Övriga ändringar och korrigeringar

Det gjordes relativt få mindre ändringar i Python 2.1 på grund av den kortare utgivningscykeln. En sökning genom CVS-ändringsloggarna visar 117 tillämpade korrigeringar och 136 åtgärdade buggar; båda siffrorna är sannolikt underskattningar. Några av de mer anmärkningsvärda ändringarna är:

  • En specialiserad objektallokering är nu tillgänglig som tillval, som bör vara snabbare än systemets malloc() och ha mindre minnesoverhead. Allokatorn använder C:s malloc()-funktion för att hämta stora minnespooler, och uppfyller sedan mindre minnesförfrågningar från dessa pooler. Den kan aktiveras genom att ange alternativet --with-pymalloc till skriptet configure; se Objects/obmalloc.c för implementeringsdetaljer.

    Författare av C-tilläggsmoduler bör testa sin kod med objektallokeringen aktiverad, eftersom en del felaktig kod kan gå sönder och orsaka kärndumpar vid körning. Det finns ett gäng minnesallokeringsfunktioner i Pythons C API som tidigare bara har varit alias för C-bibliotekets malloc() och free(), vilket innebär att om du av misstag anropade felaktiga funktioner skulle felet inte märkas. När objektallokeraren är aktiverad är dessa funktioner inte längre alias för malloc() och free(), och om du anropar fel funktion för att frigöra minne får du en kärndump. Till exempel, om minne allokerades med PyMem_New, måste det frigöras med PyMem_Del(), inte free(). Några moduler som ingår i Python drabbades av detta och måste åtgärdas; utan tvekan finns det fler moduler från tredje part som kommer att ha samma problem.

    Objektfördelaren har utvecklats av Vladimir Marangozov.

  • Hastigheten för linjeorienterad fil-I/O har förbättrats eftersom folk ofta klagar på dess bristande hastighet och eftersom den ofta har använts som ett naivt riktmärke. Metoden readline() för filobjekt har därför skrivits om för att bli mycket snabbare. Den exakta hastigheten varierar från plattform till plattform beroende på hur långsam C-bibliotekets getc() var, men den ligger runt 66%, och potentiellt mycket snabbare på vissa operativsystem. Tim Peters gjorde mycket av benchmarkingen och kodningen för den här ändringen, motiverad av en diskussion i comp.lang.python.

    En ny modul och metod för filobjekt har också lagts till, med bidrag från Jeff Epler. Den nya metoden, xreadlines(), liknar den befintliga inbyggda xrange(). xreadlines() returnerar ett ogenomskinligt sekvensobjekt som endast stöder iteration över, läser en rad vid varje iteration men inte läser hela filen i minnet som den befintliga readlines()-metoden gör. Du skulle använda den så här:

    för rad i sys.stdin.xreadlines():
        # ... gör något för varje rad ...
        ...
    

    För en mer utförlig diskussion om ändringarna av linje-I/O, se python-dev-sammandraget för 1–15 januari 2001 på https://mail.python.org/pipermail/python-dev/2001-January/.

  • En ny metod, popitem(), lades till i dictionaries för att göra det möjligt att destruktivt iterera genom innehållet i en dictionary; detta kan vara snabbare för stora dictionaries eftersom det inte finns något behov av att konstruera en lista som innehåller alla nycklar eller värden. D.popitem() tar bort ett slumpmässigt (nyckel, värde)-par från ordboken D och returnerar det som en 2-tupel. Detta implementerades huvudsakligen av Tim Peters och Guido van Rossum, efter ett förslag och en preliminär patch av Moshe Zadka.

  • Moduler kan nu kontrollera vilka namn som importeras när from module import * används, genom att definiera ett __all__-attribut som innehåller en lista med namn som ska importeras. Ett vanligt klagomål är att om modulen importerar andra moduler som sys eller string, kommer from module import * att lägga till dem i den importerande modulens namnrymd. För att åtgärda detta listar du helt enkelt de offentliga namnen i __all__:

    # Lista offentliga namn
    __all__ = ['Database', 'open']
    

    En strängare version av denna patch föreslogs och implementerades först av Ben Wolfson, men efter en del diskussioner på Python-dev checkades en svagare slutlig version in.

  • När repr() applicerades på strängar användes tidigare oktala escapes för icke-tryckbara tecken; till exempel var en ny rad '\012'. Detta var en kvarleva från Pythons C-förfäder, men idag har oktal mycket liten praktisk användning. Ka-Ping Yee föreslog att man skulle använda hex-escapes i stället för oktal-escapes och använda escapen \n, t, r för lämpliga tecken, och implementerade denna nya formatering.

  • Syntaxfel som upptäcks vid kompilering kan nu ge upphov till undantag som innehåller filnamnet och radnumret för felet, en trevlig bieffekt av den omorganisation av kompilatorn som Jeremy Hylton har gjort.

  • C-tillägg som importerar andra moduler har ändrats så att de använder PyImport_ImportModule(), vilket innebär att de kommer att använda alla import-hooks som har installerats. Detta uppmuntras även för tredjepartstillägg som behöver importera någon annan modul från C-kod.

  • Storleken på Unicodes teckendatabas krympte med ytterligare 340K tack vare Fredrik Lundh.

  • Några nya portar har bidragit: MacOS X (av Steven Majewski), Cygwin (av Jason Tishler); RISCOS (av Dietmar Schwertberger); Unixware 7 (av Billy G. Allie).

Dessutom finns den vanliga listan med mindre buggfixar, mindre minnesläckor, redigeringar av dokumentsträngar och andra justeringar, som är för långa för att vara värda att specificera; se CVS-loggarna för fullständiga detaljer om du vill ha dem.

Tack till

Författaren vill tacka följande personer för att ha kommit med förslag på olika utkast till denna artikel: Graeme Cross, David Goodger, Jay Graves, Michael Hudson, Marc-André Lemburg, Fredrik Lundh, Neil Schemenauer, Thomas Wouters.