Vad är nytt i Python 2.3

Författare:

A.M. Kuchling

I den här artikeln förklaras de nya funktionerna i Python 2.3. Python 2.3 släpptes den 29 juli 2003.

Huvudtemana för Python 2.3 är att polera några av de funktioner som lades till i 2.2, lägga till olika små men användbara förbättringar av kärnspråket och utöka standardbiblioteket. Den nya objektmodellen som introducerades i den tidigare versionen har dragit nytta av 18 månaders buggfixar och av optimeringsinsatser som har förbättrat prestandan för klasser i ny stil. Några nya inbyggda funktioner har lagts till, t.ex. sum() och enumerate(). Operatorn in kan nu användas för delsträngssökningar (t.ex. "ab" i "abc" returnerar True).

Några av de många nya biblioteksfunktionerna är datatyperna Boolean, set, heap och date/time, möjligheten att importera moduler från ZIP-formatarkiv, metadatastöd för den efterlängtade Python-katalogen, en uppdaterad version av IDLE och moduler för loggning av meddelanden, textbrytning, parsning av CSV-filer, bearbetning av kommandoradsalternativ, användning av BerkeleyDB-databaser… listan över nya och förbättrade moduler är lång.

Den här artikeln försöker inte ge en fullständig specifikation av de nya funktionerna, utan ger istället en praktisk översikt. För fullständiga detaljer bör du läsa dokumentationen för Python 2.3, till exempel Python Library Reference och Python Reference Manual. Om du vill förstå den fullständiga implementeringen och designrationaliteten, hänvisas till PEP för en viss ny funktion.

PEP 218: En datatyp för standarduppsättningar

Den nya modulen sets innehåller en implementation av datatypen set. Klassen Set är för föränderliga uppsättningar, uppsättningar som kan få medlemmar tillagda och borttagna. Klassen ImmutableSet är för uppsättningar som inte kan ändras, och instanser av ImmutableSet kan därför användas som nycklar i ordböcker. Uppsättningar byggs ovanpå ordböcker, så elementen i en uppsättning måste vara hashbara.

Här är ett enkelt exempel:

>>> import sets
>>> S = sets.Set([1,2,3])
>>> S
Set([1, 2, 3])
>>> 1 in S
True
>>> 0 in S
False
>>> S.add(5)
>>> S.remove(3)
>>> S
Set([1, 2, 5])
>>>

Union och intersektion av mängder kan beräknas med metoderna union() och intersection(); en alternativ notation använder de bitvisa operatorerna & och |. Mutabla mängder har också in-place-versioner av dessa metoder, union_update() och intersection_update().

>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([4,5,6])
>>> S1.union(S2)
Set([1, 2, 3, 4, 5, 6])
>>> S1 | S2                  # Alternative notation
Set([1, 2, 3, 4, 5, 6])
>>> S1.intersection(S2)
Set([])
>>> S1 & S2                  # Alternative notation
Set([])
>>> S1.union_update(S2)
>>> S1
Set([1, 2, 3, 4, 5, 6])
>>>

Det är också möjligt att ta den symmetriska skillnaden mellan två uppsättningar. Detta är uppsättningen av alla element i unionen som inte finns i intersektionen. Ett annat sätt att uttrycka det är att den symmetriska skillnaden innehåller alla element som finns i exakt en uppsättning. Återigen, det finns en alternativ notation (^), och en in-place version med det otympliga namnet symmetric_difference_update().

>>> S1 = sets.Set([1,2,3,4])
>>> S2 = sets.Set([3,4,5,6])
>>> S1.symmetric_difference(S2)
Set([1, 2, 5, 6])
>>> S1 ^ S2
Set([1, 2, 5, 6])
>>>

Det finns också metoderna issubset() och issuperset() för att kontrollera om en uppsättning är en delmängd eller övermängd av en annan:

>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([2,3])
>>> S2.issubset(S1)
True
>>> S1.issubset(S2)
False
>>> S1.issuperset(S2)
True
>>>

Se även

PEP 218 - Lägga till en inbyggd objekttyp för set

PEP skriven av Greg V. Wilson. Implementerad av Greg V. Wilson, Alex Martelli och GvR.

PEP 255: Enkla generatorer

I Python 2.2 lades generatorer till som en valfri funktion som kunde aktiveras med ett from __future__ import generators-direktiv. I 2.3 behöver generatorer inte längre aktiveras speciellt, utan är nu alltid närvarande; detta innebär att yield nu alltid är ett nyckelord. Resten av det här avsnittet är en kopia av beskrivningen av generatorer från dokumentet ”What’s New in Python 2.2”; om du läste det när Python 2.2 kom ut kan du hoppa över resten av det här avsnittet.

Du är säkert bekant med hur funktionsanrop fungerar i Python eller C. När du anropar en funktion får den ett privat namnrymd där dess lokala variabler skapas. När funktionen når en return-sats förstörs de lokala variablerna och det resulterande värdet returneras till anroparen. Ett senare anrop till samma funktion kommer att få en ny uppsättning lokala variabler. Men tänk om de lokala variablerna inte kastades bort när en funktion avslutades? Tänk om du senare kunde återuppta funktionen där den slutade? Detta är vad generatorer tillhandahåller; de kan betraktas som återupptagbara funktioner.

Här är det enklaste exemplet på en generatorfunktion:

def generera_ints(N):
    för i i intervall(N):
        avkastning i

Ett nytt nyckelord, yield, introducerades för generatorer. Alla funktioner som innehåller en yield-sats är en generatorfunktion; detta upptäcks av Pythons bytecode-kompilator som kompilerar funktionen speciellt som ett resultat.

När du anropar en generatorfunktion returnerar den inte ett enda värde, utan istället ett generatorobjekt som stöder iteratorprotokollet. Vid exekvering av yield-satsen matar generatorn ut värdet på i, på samma sätt som en return-sats. Den stora skillnaden mellan yield och en return-sats är att när man når en yield avbryts generatorns exekveringstillstånd och lokala variabler bevaras. Vid nästa anrop till generatorns metod .next() kommer funktionen att återuppta exekveringen omedelbart efter yield-satsen. (Av komplicerade skäl är yield-satsen inte tillåten inuti try-blocket i en tryfinally-sats; läs PEP 255 för en fullständig förklaring av interaktionen mellan yield och undantag)

Här är ett exempel på användning av generatorn generate_ints():

>>> gen = generate_ints(3)
>>> gen
<generator object at 0x8117f90>
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
Traceback (most recent call last):
  File "stdin", line 1, in ?
  File "stdin", line 2, in generate_ints
StopIteration

Du kan lika gärna skriva for i in generate_ints(5), eller a,b,c = generate_ints(3).

I en generatorfunktion kan return bara användas utan ett värde och signalerar slutet på värdeförloppet; därefter kan generatorn inte returnera några ytterligare värden. return med ett värde, t.ex. return 5, är ett syntaxfel i en generatorfunktion. Slutet på generatorns resultat kan också indikeras genom att höja StopIteration manuellt, eller genom att bara låta flödet av exekveringen falla från botten av funktionen.

Du kan uppnå effekten av generatorer manuellt genom att skriva din egen klass och lagra alla lokala variabler i generatorn som instansvariabler. Att returnera en lista med heltal kan till exempel göras genom att sätta self.count till 0 och låta next()-metoden öka self.count och returnera den. Men för en måttligt komplicerad generator skulle det vara mycket krångligare att skriva en motsvarande klass. Lib/test/test_generators.py innehåller ett antal mer intressanta exempel. Det enklaste implementerar en genomgång av ett träd i ordningsföljd med hjälp av generatorer rekursivt.

# En rekursiv generator som genererar trädblad i ordning.
def inorder(t):
    if t:
        för x i inorder(t.left):
            avkastning x
        yield t.etikett
        för x i inorder(t.right):
            ge x

Två andra exempel i Lib/test/test_generators.py producerar lösningar för N-Queens-problemet (placera $N$ drottningar på ett $NxN$ schackbräde så att ingen drottning hotar en annan) och Knight’s Tour (en rutt som tar en springare till varje ruta på ett $NxN$ schackbräde utan att besöka någon ruta två gånger).

Idén med generatorer kommer från andra programmeringsspråk, särskilt Icon (https://www2.cs.arizona.edu/icon/), där idén med generatorer är central. I Icon beter sig varje uttryck och funktionsanrop som en generator. Ett exempel från ”An Overview of the Icon Programming Language” på https://www2.cs.arizona.edu/icon/docs/ipd266.htm ger en uppfattning om hur detta ser ut:

mening := "Förvara den i den närliggande hamnen"
if (i := find("eller", mening)) > 5  skriv(i)

I Icon returnerar funktionen find() de index där delsträngen ”or” hittas: 3, 23, 33. I if-satsen tilldelas i först värdet 3, men 3 är mindre än 5, så jämförelsen misslyckas, och Icon gör ett nytt försök med det andra värdet 23. 23 är större än 5, så jämförelsen lyckas nu, och koden skriver ut värdet 23 på skärmen.

Python går inte alls lika långt som Icon när det gäller att anta generatorer som ett centralt koncept. Generatorer anses vara en del av Pythons kärnspråk, men det är inte obligatoriskt att lära sig eller använda dem; om de inte löser några problem som du har, känn dig fri att ignorera dem. En nyhet i Pythons gränssnitt jämfört med Icons är att en generators tillstånd representeras som ett konkret objekt (iteratorn) som kan skickas runt till andra funktioner eller lagras i en datastruktur.

Se även

PEP 255 - Enkla generatorer

Skriven av Neil Schemenauer, Tim Peters, Magnus Lie Hetland. Implementerad mestadels av Neil Schemenauer och Tim Peters, med andra korrigeringar från Python Labs-gänget.

PEP 263: Kodning av källkod

Python-källfiler kan nu deklareras med olika teckenuppsättningskodningar. Kodningar deklareras genom att inkludera en speciellt formaterad kommentar på den första eller andra raden i källfilen. Till exempel kan en UTF-8-fil deklareras med:

#!/usr/bin/env python
# -*- kodning: UTF-8 -*-

Utan en sådan kodningsdeklaration används 7-bitars ASCII som standardkodning. Att exekvera eller importera moduler som innehåller stränglitteraler med 8-bitars tecken och som inte har någon kodningsdeklaration kommer att resultera i en DeprecationWarning som signaleras av Python 2.3; i 2.4 kommer detta att vara ett syntaxfel.

Kodningsdeklarationen påverkar endast Unicode-stränglitteraler, som kommer att konverteras till Unicode med hjälp av den angivna kodningen. Observera att Python-identifierare fortfarande är begränsade till ASCII-tecken, så du kan inte ha variabelnamn som använder tecken utanför de vanliga alfanumeriska tecknen.

Se även

PEP 263 - Definiera Python-kodning av källkod

Skriven av Marc-André Lemburg och Martin von Löwis; implementerad av Suzuki Hisao och Martin von Löwis.

PEP 273: Importera moduler från ZIP-arkiv

Den nya modulen zipimport ger stöd för att importera moduler från ett ZIP-arkiv. Du behöver inte importera modulen explicit; den importeras automatiskt om ZIP-arkivets filnamn läggs till i sys.path. Ett exempel:

amk@nyman:~/src/python$ unzip -l /tmp/example.zip
Archive:  /tmp/example.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
     8467  11-26-02 22:30   jwzthreading.py
 --------                   -------
     8467                   1 file
amk@nyman:~/src/python$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32)
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'
>>>

En post i sys.path kan nu vara filnamnet på ett ZIP-arkiv. ZIP-arkivet kan innehålla alla typer av filer, men endast filer med namnet *.py, *.pyc eller *.pyo kan importeras. Om ett arkiv endast innehåller *.py-filer kommer Python inte att försöka modifiera arkivet genom att lägga till motsvarande *.pyc-fil, vilket innebär att om ett ZIP-arkiv inte innehåller *.pyc-filer kan importen gå ganska långsamt.

En sökväg inom arkivet kan också anges för att endast importera från en underkatalog; till exempel skulle sökvägen /tmp/example.zip/lib/ endast importera från underkatalogen lib/ inom arkivet.

Se även

PEP 273 - Importera moduler från zip-arkiv

Skriven av James C. Ahlstrom, som också tillhandahöll en implementation. Python 2.3 följer specifikationen i PEP 273, men använder en implementation skriven av Just van Rossum som använder de import-hooks som beskrivs i PEP 302. Se avsnitt PEP 302: Nya import-hooks för en beskrivning av de nya importkrokarna.

PEP 277: Stöd för Unicode-filnamn i Windows NT

I Windows NT, 2000 och XP lagrar systemet filnamn som Unicode-strängar. Traditionellt har Python representerat filnamn som bytesträngar, vilket är otillräckligt eftersom det gör vissa filnamn otillgängliga.

Python tillåter nu användning av godtyckliga Unicode-strängar (inom filsystemets begränsningar) för alla funktioner som förväntar sig filnamn, framför allt den inbyggda funktionen open(). Om en Unicode-sträng skickas till os.listdir() returnerar Python nu en lista med Unicode-strängar. En ny funktion, os.getcwdu(), returnerar den aktuella katalogen som en Unicode-sträng.

Byte-strängar fungerar fortfarande som filnamn, och på Windows konverterar Python dem transparent till Unicode med hjälp av kodningen mbcs.

Andra system tillåter också Unicode-strängar som filnamn men konverterar dem till byte-strängar innan de skickas till systemet, vilket kan leda till att ett UnicodeError uppstår. Program kan testa om godtyckliga Unicode-strängar stöds som filnamn genom att kontrollera os.path.supports_unicode_filenames, ett booleskt värde.

Under MacOS kan os.listdir() nu returnera Unicode-filnamn.

Se även

PEP 277 - Stöd för Unicode-filnamn i Windows NT

Skriven av Neil Hodgson; implementerad av Neil Hodgson, Martin von Löwis och Mark Hammond.

PEP 278: Universellt stöd för nya linjer

De tre största operativsystemen som används idag är Microsoft Windows, Apples Macintosh OS och de olika Unix-derivaten. Ett litet irritationsmoment när man arbetar plattformsoberoende är att de tre plattformarna använder olika tecken för att markera slutet på rader i textfiler. Unix använder linefeed (ASCII-tecken 10), MacOS använder carriage return (ASCII-tecken 13) och Windows använder en sekvens med två tecken, carriage return och en ny rad.

Pythons filobjekt kan nu stödja andra konventioner för radavslut än den som följs av den plattform som Python körs på. Att öppna en fil med läget 'U' eller 'rU' kommer att öppna en fil för läsning i universal newlines-läget. Alla tre radslutskonventionerna kommer att översättas till '\n' i strängarna som returneras av de olika filmetoderna som read() och readline().

Universellt stöd för nya rader används också vid import av moduler och när en fil exekveras med funktionen execfile(). Detta innebär att Python-moduler kan delas mellan alla tre operativsystemen utan att radavslutningarna behöver konverteras.

Denna funktion kan avaktiveras vid kompilering av Python genom att ange --without-universal-newlines när Pythons configure-skript körs.

Se även

PEP 278 - Universellt stöd för nya linjer

Skriven och implementerad av Jack Jansen.

PEP 279: enumerate()

En ny inbyggd funktion, enumerate(), kommer att göra vissa loopar lite tydligare. enumerate(thing), där thing är antingen en iterator eller en sekvens, returnerar en iterator som returnerar (0, thing[0]), (1, thing[1]), (2, thing[2]), och så vidare.

Ett vanligt idiom för att ändra varje element i en lista ser ut så här:

for i in range(len(L)):
    objekt = L[i]
    # ... beräkna något resultat baserat på item ...
    L[i] = resultat

Detta kan skrivas om med hjälp av enumerate() som:

för i, objekt i enumerate(L):
    # ... beräkna ett resultat baserat på objektet ...
    L[i] = resultat

Se även

PEP 279 - Den inbyggda funktionen enumerate()

Skriven och implementerad av Raymond D. Hettinger.

PEP 282: Loggningspaketet

Ett standardpaket för att skriva loggar, logging, har lagts till i Python 2.3. Det ger en kraftfull och flexibel mekanism för att generera loggningsutdata som sedan kan filtreras och bearbetas på olika sätt. En konfigurationsfil skriven i ett standardformat kan användas för att styra loggningsbeteendet i ett program. Python innehåller hanterare som skriver loggposter till standardfel eller till en fil eller socket, skickar dem till systemloggen eller till och med e-postar dem till en viss adress; naturligtvis är det också möjligt att skriva egna hanterarklasser.

Klassen Logger är den primära klassen. Den mesta programkoden kommer att hantera ett eller flera Logger-objekt, som vart och ett används av ett visst delsystem i programmet. Varje Logger identifieras med ett namn, och namnen organiseras i en hierarki med . som komponentavgränsare. Du kan t.ex. ha Logger-instanser med namnen server, server.auth och server.network. De två sistnämnda instanserna ligger under server i hierarkin. Detta innebär att om du ökar ordrikedomen för server eller riktar server-meddelanden till en annan hanterare, kommer ändringarna också att gälla för poster som loggas till server.auth och server.network. Det finns också en rot Logger som är överordnad alla andra loggrar.

För enkla användningsområden innehåller paketet logging några bekvämlighetsfunktioner som alltid använder roten log:

import logging

logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')

Detta ger följande utdata:

WARNING:root:Warning:config-filen server.conf hittades inte
ERROR:root:Fel inträffade
CRITICAL:root:Kritiskt fel -- stänger ner

I standardkonfigurationen undertrycks informations- och felsökningsmeddelanden och utdata skickas till standardfel. Du kan aktivera visning av informations- och felsökningsmeddelanden genom att anropa metoden setLevel() på rotloggaren.

Lägg märke till warning()-anropets användning av strängformateringsoperatorer; alla funktioner för loggning av meddelanden tar argumenten (msg, arg1, arg2, ...) och loggar strängen som blir resultatet av msg % (arg1, arg2, ...).

Det finns också en exception()-funktion som registrerar det senaste bakslaget. Någon av de andra funktionerna kommer också att spela in spårningen om du anger ett sant värde för nyckelordsargumentet exc_info.

def f():
    försök:    1/0
    except: logging.exception('Problem registrerat')

f()

Detta ger följande utdata:

ERROR:root:Problem registrerat
Återkoppling (senaste anropet sist):
  Fil "t.py", rad 6, i f
    1/0
ZeroDivisionError: division av heltal eller modulo med noll

Lite mer avancerade program kommer att använda en annan logger än rotloggern. Funktionen getLogger(name) används för att hämta en viss logger, och skapar den om den inte finns ännu. getLogger(None) returnerar rotloggaren.

log = loggning.getLogger('server')
 ...
log.info('Lyssnar på port %i', port)
 ...
log.critical('Disk full')
 ...

Loggposter sprids vanligtvis uppåt i hierarkin, så ett meddelande som loggas till server.auth ses också av server och root, men en Logger kan förhindra detta genom att ställa in dess propagate-attribut till False.

Det finns fler klasser som tillhandahålls av paketet logging och som kan anpassas. När en instans av Logger får i uppdrag att logga ett meddelande skapas en instans av LogRecord som skickas till ett valfritt antal olika instanser av Handler. Loggare och hanterare kan också ha en bifogad lista med filter, och varje filter kan orsaka att LogRecord ignoreras eller kan modifiera posten innan den skickas vidare. När de slutligen skrivs ut konverteras LogRecord-instanser till text av en Formatter-klass. Alla dessa klasser kan ersättas av dina egna specialskrivna klasser.

Med alla dessa funktioner bör paketet logging ge tillräcklig flexibilitet för även de mest komplicerade tillämpningarna. Det här är bara en ofullständig översikt över dess funktioner, så se paketets referensdokumentation för alla detaljer. Att läsa PEP 282 kommer också att vara till hjälp.

Se även

PEP 282 - Ett loggningssystem

Skriven av Vinay Sajip och Trent Mick; implementerad av Vinay Sajip.

PEP 285: En boolesk typ

En boolesk typ lades till i Python 2.3. Två nya konstanter lades till i modulen __builtin__, True och False. (True och False lades till i Python 2.2.1, men 2.2.1-versionerna är helt enkelt inställda på heltalsvärdena 1 och 0 och är inte en annan typ)

Typobjektet för den här nya typen heter bool; konstruktören för den tar ett valfritt Python-värde och konverterar det till True eller False.

>>> bool(1)
True
>>> bool(0)
False
>>> bool([])
False
>>> bool( (1,) )
True

De flesta av standardbibliotekets moduler och inbyggda funktioner har ändrats så att de returnerar booleaner:

>>> obj = []
>>> hasattr(obj, 'append')
True
>>> isinstance(obj, list)
True
>>> isinstance(obj, tuple)
False

Pythons booleaner lades till med det primära målet att göra koden tydligare. Om du till exempel läser en funktion och stöter på uttalandet return 1, kanske du undrar om 1 representerar ett booleskt sanningsvärde, ett index eller en koefficient som multiplicerar någon annan kvantitet. Om uttalandet är return True är dock betydelsen av returvärdet ganska tydlig.

Pythons booleaner lades inte till för att göra en strikt typkontroll. Ett mycket strikt språk som Pascal skulle också hindra dig från att utföra aritmetik med booleaner och skulle kräva att uttrycket i en if-sats alltid utvärderas till ett booleanskt resultat. Python är inte så strikt och kommer aldrig att bli det, vilket PEP 285 uttryckligen säger. Detta innebär att du fortfarande kan använda vilket uttryck som helst i en if-sats, även sådana som utvärderas till en lista eller tupel eller något slumpmässigt objekt. Den booleska typen är en underklass till int-klassen så att aritmetik med en booleansk typ fortfarande fungerar.

>>> True + 1
2
>>> False + 1
1
>>> False * 75
0
>>> True * 75
75

För att sammanfatta True och False i en mening: de är alternativa sätt att stava till heltalsvärdena 1 och 0, med den enda skillnaden att str() och repr() returnerar strängarna 'True' och 'False' istället för '1' och '0'.

Se även

PEP 285 - Lägga till en bool-typ

Skrivet och implementerat av GvR.

PEP 293: Callbacks för felhantering av codec

När man kodar en Unicode-sträng till en byte-sträng kan man stöta på tecken som inte kan kodas. Hittills har Python tillåtit att felhanteringen specificeras som antingen ”strict” (väcker UnicodeError), ”ignore” (hoppar över tecknet) eller ”replace” (använder ett frågetecken i utdatasträngen), där ”strict” är standardbeteendet. Det kan vara önskvärt att ange alternativ behandling av sådana fel, t.ex. att infoga en XML-teckenreferens eller HTML-entitetsreferens i den konverterade strängen.

Python har nu ett flexibelt ramverk för att lägga till olika bearbetningsstrategier. Nya felhanterare kan läggas till med codecs.register_error(), och codecs kan sedan komma åt felhanteraren med codecs.lookup_error(). Ett motsvarande C-API har lagts till för codecs som är skrivna i C. Felhanteraren får nödvändig statusinformation, t.ex. strängen som konverteras, positionen i strängen där felet upptäcktes och målkodningen. Hanteraren kan sedan antingen skapa ett undantag eller returnera en ersättningssträng.

Två ytterligare felhanterare har implementerats med hjälp av detta ramverk: ”backslashreplace” använder Pythons backslash-citering för att representera okodbara tecken och ”xmlcharrefreplace” skickar ut XML-teckenreferenser.

Se även

PEP 293 - Återkallelser för felhantering av codec

Skrivet och implementerat av Walter Dörwald.

PEP 301: Paketindex och metadata för Distutils

Stöd för den sedan länge efterfrågade Python-katalogen finns för första gången i 2.3.

Hjärtat i katalogen är det nya Distutils register-kommandot. Genom att köra python setup.py register samlas de metadata som beskriver ett paket in, t.ex. namn, version, underhållare, beskrivning etc., och skickas till en central katalogserver. Den resulterande katalogen finns tillgänglig från https://pypi.org.

För att göra katalogen lite mer användbar har ett nytt valfritt classifiers-nyckelordsargument lagts till i Distutils setup()-funktion. En lista med strängar i stil med Trove kan anges för att hjälpa till att klassificera programvaran.

Här är ett exempel setup.py med klassificerare, skriven för att vara kompatibel med äldre versioner av Distutils:

från distutils import core
kw = {'namn': "Quixote",
      'version': "0.5.1",
      'description': "Ett mycket pythoniskt ramverk för webbapplikationer",
      # ...
      }

if (hasattr(core, 'setup_keywords') och
    "classifiers" i core.setup_keywords):
    kw['classifiers'] = \
        ['Ämne :: Internet :: WWW/HTTP :: Dynamic Content',
         "Miljö :: Ingen inmatning/utmatning (Daemon)",
         'Avsedd målgrupp :: Utvecklare'],

core.setup(**kw)

Den fullständiga listan över klassificerare kan erhållas genom att köra python setup.py register --list-classifiers.

Se även

PEP 301 - Paketindex och metadata för Distutils

Skrivet och implementerat av Richard Jones.

PEP 302: Nya import-hooks

Även om det har varit möjligt att skriva egna import-hooks ända sedan modulen ihooks introducerades i Python 1.3, har ingen någonsin varit riktigt nöjd med det eftersom det är svårt och rörigt att skriva nya import-hooks. Det har funnits olika föreslagna alternativ som modulerna imputil och iu, men ingen av dem har någonsin fått någon större acceptans, och ingen av dem var lätt att använda från C-kod.

PEP 302 lånar idéer från sina föregångare, särskilt från Gordon McMillans modul iu. Tre nya objekt har lagts till i modulen sys:

  • sys.path_hooks är en lista över anropsbara objekt; oftast är de klasser. Varje anropbart objekt tar en sträng som innehåller en sökväg och returnerar antingen ett importobjekt som hanterar import från denna sökväg eller ger upphov till ett ImportError-undantag om det inte kan hantera denna sökväg.

  • sys.path_importer_cache cachelagrar importobjekt för varje sökväg, så sys.path_hooks behöver bara passeras en gång för varje sökväg.

  • sys.meta_path är en lista över importerarobjekt som kommer att genomkorsas innan sys.path kontrolleras. Den här listan är från början tom, men användarkod kan lägga till objekt i den. Ytterligare inbyggda och frysta moduler kan importeras av ett objekt som läggs till i den här listan.

Importörobjekt måste ha en enda metod, find_module(fullname, path=None). fullname kommer att vara ett modul- eller paketnamn, t.ex. string eller distutils.core. find_module() måste returnera ett laddningsobjekt som har en enda metod, load_module(fullname), som skapar och returnerar motsvarande modulobjekt.

Pseudokoden för Pythons nya importlogik ser därför ut ungefär så här (lite förenklat; se PEP 302 för fullständiga detaljer):

för mp i sys.meta_path:
    loader = mp(fullständigt namn)
    om loader inte är None:
        <module> = loader.load_module(fullname)

for path in sys.path:
    för hook i sys.path_hooks:
        försök:
            importer = hook(sökväg)
        except ImportError:
            # ImportError, så prova de andra sökvägskrokarna
            passera
        else:
            loader = importer.find_module(fullname)
            <module> = loader.load_module(fullständigt namn)

# Hittades inte!
höja ImportError

Se även

PEP 302 - Nya import-hooks

Skrivet av Just van Rossum och Paul Moore. Implementerad av Just van Rossum.

PEP 305: Kommaseparerade filer

Kommaseparerade filer är ett format som ofta används för att exportera data från databaser och kalkylblad. Python 2.3 lägger till en parser för kommaseparerade filer.

Kommaseparerat format är bedrägligt enkelt vid första anblicken:

Kostnader,150,200,3,95

Läs en rad och anropa line.split(','): vad kan vara enklare? Men släng in strängdata som kan innehålla kommatecken, och saker och ting blir mer komplicerade:

"Kostnader",150,200,3,95,"Inkluderar skatter, frakt och diverse"

Ett stort fult reguljärt uttryck kan analysera detta, men det är mycket enklare att använda det nya csv-paketet:

import csv

input = open('datafile', 'rb')
reader = csv.reader(input)
for line in reader:
    print line

Funktionen reader() tar emot ett antal olika alternativ. Fältavgränsaren är inte begränsad till kommatecken utan kan ändras till vilket tecken som helst, och det kan även citattecken och radavslutningstecken.

Olika dialekter av kommaseparerade filer kan definieras och registreras; för närvarande finns det två dialekter, som båda används av Microsoft Excel. En separat csv.writer-klass genererar kommaseparerade filer från en följd av tupler eller listor, och citerar strängar som innehåller avgränsaren.

Se även

PEP 305 - API för CSV-filer

Skriven och implementerad av Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells.

PEP 307: Pickle-förbättringar

Modulerna pickle och cPickle fick en del uppmärksamhet under utvecklingscykeln för 2.3. I 2.2 kunde klasser av ny typ picklas utan problem, men de picklades inte särskilt kompakt; PEP 307 citerar ett trivialt exempel där en klass av ny typ resulterar i en picklad sträng som är tre gånger längre än för en klassisk klass.

Lösningen var att uppfinna ett nytt pickle-protokoll. Funktionen pickle.dumps() har länge haft stöd för en text-eller-binärflagga. I 2.3 omdefinieras denna flagga från en boolesk till ett heltal: 0 är det gamla pickle-formatet i textläge, 1 är det gamla binära formatet och nu är 2 ett nytt 2.3-specifikt format. En ny konstant, pickle.HIGHEST_PROTOCOL, kan användas för att välja det snyggaste tillgängliga protokollet.

Unpickling anses inte längre vara en säker operation. 2.2:s pickle tillhandahöll hooks för att försöka förhindra osäkra klasser från att avplockas (specifikt ett __safe_for_unpickling__-attribut), men ingen av denna kod granskades någonsin och därför har allt tagits bort i 2.3. Du bör inte unpickle otillförlitlig data i någon version av Python.

För att minska kostnaderna för pickling för klasser av ny typ lades ett nytt gränssnitt till för att anpassa pickling med hjälp av tre specialmetoder: __getstate__(), __setstate__() och __getnewargs__(). Se PEP 307 för den fullständiga semantiken för dessa metoder.

Som ett sätt att komprimera pickles ytterligare är det nu möjligt att använda heltalskoder istället för långa strängar för att identifiera picklade klasser. Python Software Foundation kommer att upprätthålla en lista med standardiserade koder; det finns också en rad koder för privat bruk. För närvarande har inga koder specificerats.

Se även

PEP 307 - Tillägg till pickle-protokollet

Skriven och implementerad av Guido van Rossum och Tim Peters.

Förlängda skivor

Ända sedan Python 1.4 har slicing-syntaxen haft stöd för ett valfritt tredje ”step”- eller ”stride”-argument. Till exempel är dessa alla lagliga Python-syntaxer: L[1:10:2], L[:-1:1], L[::-1]. Detta lades till i Python på begäran av utvecklarna av Numerical Python, som använder det tredje argumentet i stor utsträckning. Pythons inbyggda list-, tuple- och strängsequenstyper har dock aldrig haft stöd för den här funktionen, och gav upphov till ett TypeError om man försökte. Michael Hudson bidrog med en patch för att åtgärda denna brist.

Till exempel kan du nu enkelt extrahera de element i en lista som har jämna index:

>>> L = range(10)
>>> L[::2]
[0, 2, 4, 6, 8]

Negativa värden fungerar också för att göra en kopia av samma lista i omvänd ordning:

>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Detta fungerar även för tupler, arrayer och strängar:

>>> s='abcd'
>>> s[::2]
'ac'
>>> s[::-1]
'dcba'

Om du har en föränderlig sekvens, t.ex. en lista eller en array, kan du tilldela eller ta bort en extended slice, men det finns vissa skillnader mellan tilldelning till extended och regular slices. Tilldelning till en vanlig skiva kan användas för att ändra längden på sekvensen:

>>> a = range(3)
>>> a
[0, 1, 2]
>>> a[1:3] = [4, 5, 6]
>>> a
[0, 4, 5, 6]

Extended slices är inte lika flexibla. Vid tilldelning till en utökad slice måste listan på höger sida av uttalandet innehålla samma antal poster som den slice den ersätter:

>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> a[::2] = [0, -1]
>>> a
[0, 1, -1, 3]
>>> a[::2] = [0,1,2]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: attempt to assign sequence of size 3 to extended slice of size 2

Radering är mer okomplicerat:

>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> del a[::2]
>>> a
[1, 3]

Man kan nu också skicka slice-objekt till __getitem__()-metoderna i de inbyggda sekvenserna:

>>> range(10).__getitem__(slice(0, 5, 2))
[0, 2, 4]

Eller använd slice-objekt direkt i subscripts:

>>> range(10)[slice(0, 5, 2)]
[0, 2, 4]

För att förenkla implementeringen av sekvenser som stöder utökad skivning har slice-objekt nu en metod indices(length) som, givet längden på en sekvens, returnerar en (start, stop, step)-tupel som kan skickas direkt till range(). indices() hanterar utelämnade och obegränsade index på ett sätt som överensstämmer med vanliga slices (och denna oskyldiga fras döljer en mängd förvirrande detaljer!) Metoden är avsedd att användas så här:

klass FakeSeq:
    ...
    def calc_item(self, i):
        ...
    def __getitem__(self, item):
        if isinstance(item, slice):
            index = objekt.index(len(self))
            return FakeSeq([self.calc_item(i) for i in range(*indices)])
        annat:
            return self.calc_item(i)

Från detta exempel kan du också se att det inbyggda slice-objektet nu är typobjektet för slice-typen och inte längre är en funktion. Detta stämmer överens med Python 2.2, där int, str, etc. genomgick samma förändring.

Andra språkliga förändringar

Här är alla ändringar som Python 2.3 gör i kärnan i Python-språket.

  • Satsen yield är nu alltid ett nyckelord, enligt beskrivningen i avsnitt PEP 255: Enkla generatorer i detta dokument.

  • En ny inbyggd funktion enumerate() lades till, som beskrivs i avsnitt PEP 279: enumerate() i detta dokument.

  • Två nya konstanter, True och False lades till tillsammans med den inbyggda typen bool, enligt beskrivningen i avsnitt PEP 285: En boolesk typ i detta dokument.

  • Typkonstruktören int() returnerar nu ett långt heltal istället för att ge upphov till ett OverflowError när en sträng eller ett flyttal är för stort för att rymmas i ett heltal. Detta kan leda till det paradoxala resultatet att isinstance(int(expression), int) är falskt, men det verkar osannolikt att det kommer att orsaka problem i praktiken.

  • Inbyggda typer stöder nu den utökade slicing-syntaxen, som beskrivs i avsnitt Förlängda skivor i detta dokument.

  • En ny inbyggd funktion, sum(iterable, start=0), adderar de numeriska objekten i iterable-objektet och returnerar summan av dem. sum() accepterar bara siffror, vilket innebär att du inte kan använda den för att sammanfoga en massa strängar. (Bidrag från Alex Martelli.)

  • list.insert(pos, value) brukade infoga värde längst fram i listan när pos var negativ. Beteendet har nu ändrats så att det stämmer överens med slice-indexering, så när pos är -1 kommer värdet att infogas före det sista elementet, och så vidare.

  • list.index(value), som söker efter värde i listan och returnerar dess index, tar nu valfria start och stop argument för att begränsa sökningen till endast en del av listan.

  • Dictionaries har en ny metod, pop(key[, *default*]), som returnerar det värde som motsvarar key och tar bort det nyckel/värde-paret från dictionaryn. Om den begärda nyckeln inte finns i ordboken returneras default om den är specificerad och KeyError om den inte är det.

    >>> d = {1:2}
    >>> d
    {1: 2}
    >>> d.pop(4)
    Traceback (most recent call last):
      File "stdin", line 1, in ?
    KeyError: 4
    >>> d.pop(1)
    2
    >>> d.pop(1)
    Traceback (most recent call last):
      File "stdin", line 1, in ?
    KeyError: 'pop(): dictionary is empty'
    >>> d
    {}
    >>>
    

    Det finns också en ny klassmetod, dict.fromkeys(iterable, value), som skapar en ordbok med nycklar som hämtas från den medföljande iteratorn iterable och alla värden sätts till value, med standardvärdet None.

    (Lapparna har tillhandahållits av Raymond Hettinger.)

    Dessutom accepterar dict()-konstruktören nu nyckelordsargument för att förenkla skapandet av små ordböcker:

    >>> dict(red=1, blue=2, green=3, black=4)
    {'blue': 2, 'black': 4, 'green': 3, 'red': 1}
    

    (Bidrag från Just van Rossum.)

  • Satsen assert kontrollerar inte längre flaggan __debug__, så du kan inte längre inaktivera påståenden genom att tilldela till __debug__. Att köra Python med -O kommer fortfarande att generera kod som inte utför några assertions.

  • De flesta typobjekt är nu anropsbara, så att du kan använda dem för att skapa nya objekt som funktioner, klasser och moduler. (Detta innebär att modulen new kan tas bort i en framtida Python-version, eftersom du nu kan använda de typobjekt som finns i modulen types) Du kan till exempel skapa ett nytt modulobjekt med följande kod:

    >>> import types
    >>> m = types.ModuleType('abc','docstring')
    >>> m
    <module 'abc' (built-in)>
    >>> m.__doc__
    'docstring'
    
  • En ny varning, PendingDeprecationWarning, har lagts till för att indikera funktioner som håller på att bli föråldrade. Varningen kommer inte att skrivas ut som standard. För att kontrollera om funktioner som kommer att föråldras används i framtiden, ange -Walways::PendingDeprecationWarning:: på kommandoraden eller använd warnings.filterwarnings().

  • Processen med att avskriva strängbaserade undantag, som i raise "Error occurred", har börjat. Om en sträng anges kommer den nu att utlösa PendingDeprecationWarning.

  • Att använda None som variabelnamn kommer nu att resultera i en SyntaxWarning-varning. I en framtida version av Python kan None äntligen bli ett nyckelord.

  • Metoden xreadlines() för filobjekt, som introducerades i Python 2.1, är inte längre nödvändig eftersom filer nu beter sig som sin egen iterator. xreadlines() introducerades ursprungligen som ett snabbare sätt att loopa över alla rader i en fil, men nu kan du helt enkelt skriva for line in file_obj. Filobjekt har också ett nytt skrivskyddat attribut encoding som anger den kodning som används av filen; Unicode-strängar som skrivs till filen konverteras automatiskt till bytes med den angivna kodningen.

  • Den metodupplösningsordning som används av new-style klasser har ändrats, men du kommer bara att märka skillnaden om du har en riktigt komplicerad arvshierarki. Klassiska klasser påverkas inte av denna förändring. Python 2.2 använde ursprungligen en topologisk sortering av en klass förfäder, men 2.3 använder nu C3-algoritmen som beskrivs i dokumentet ”A Monotonic Superclass Linearization for Dylan”. För att förstå motivationen för denna förändring, läs Michele Simionatos artikel Python 2.3-metodens upplösningsordning, eller läs tråden på python-dev som börjar med meddelandet på https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele Pedroni påpekade först problemet och implementerade också lösningen genom att koda C3-algoritmen.

  • Python kör flertrådade program genom att växla mellan trådar efter att N bytekoder har exekverats. Standardvärdet för N har ökats från 10 till 100 bytekoder, vilket snabbar upp enkeltrådade applikationer genom att minska växlingsomkostnaderna. Vissa flertrådade program kan få långsammare svarstid, men det är lätt att åtgärda genom att sätta tillbaka gränsen till ett lägre värde med hjälp av sys.setcheckinterval(N). Gränsen kan hämtas med den nya funktionen sys.getcheckinterval().

  • En mindre men långtgående förändring är att namnen på tilläggstyper som definieras av de moduler som ingår i Python nu innehåller modulen och en '.' framför typnamnet. Om du till exempel i Python 2.2 skapade en socket och skrev ut dess __class__, skulle du få följande resultat:

    >>> s = socket.socket()
    >>> s.__class__
    <type 'socket'>
    

    I 2.3 får du detta:

    >>> s.__class__
    <type '_socket.socket'>
    
  • En av de noterade inkompatibiliteterna mellan gamla och nya klasser har tagits bort: du kan nu tilldela attributen __name__ och __bases__ till nya klasser. Det finns vissa restriktioner för vad som kan tilldelas __bases__ i linje med de som gäller för att tilldela en instans attribut __class__.

Strängförändringar

  • Operatorn in fungerar nu annorlunda för strängar. Tidigare kunde X bara vara ett enda tecken vid utvärdering av X in Y där X och Y är strängar. Det har nu ändrats; X kan vara en sträng av valfri längd, och X in Y returnerar True om X är en delsträng av Y. Om X är den tomma strängen är resultatet alltid True.

    >>> 'ab' in 'abcd'
    True
    >>> 'ad' in 'abcd'
    False
    >>> '' in 'abcd'
    True
    

    Observera att detta inte berättar var delsträngen börjar; om du behöver den informationen använder du strängmetoden find().

  • Strängmetoderna strip(), lstrip() och rstrip() har nu ett valfritt argument för att ange vilka tecken som ska tas bort. Standardinställningen är fortfarande att ta bort alla blankstegstecken:

    >>> '   abc '.strip()
    'abc'
    >>> '><><abc<><><>'.strip('<>')
    'abc'
    >>> '><><abc<><><>\n'.strip('<>')
    'abc<><><>\n'
    >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000')
    u'\u4001abc'
    >>>
    

    (Föreslagen av Simon Brunning och implementerad av Walter Dörwald.)

  • Strängmetoderna startswith() och endswith() accepterar nu negativa tal för parametrarna start och end.

  • En annan ny strängmetod är zfill(), som ursprungligen var en funktion i modulen string. zfill() fyller en numerisk sträng med nollor till vänster tills den har den angivna bredden. Observera att operatorn % fortfarande är mer flexibel och kraftfull än zfill().

    >>> '45'.zfill(4)
    '0045'
    >>> '12345'.zfill(4)
    '12345'
    >>> 'goofy'.zfill(6)
    '0goofy'
    

    (Bidrag från Walter Dörwald.)

  • En ny typ av objekt, basestring, har lagts till. Både 8-bitars strängar och Unicode-strängar ärver från den här typen, så isinstance(obj, basestring) kommer att returnera True för båda typerna av strängar. Det är en helt abstrakt typ, så du kan inte skapa basestring-instanser.

  • Internerade strängar är inte längre odödliga och kommer nu att samlas in på vanligt sätt när den enda referensen till dem är från den interna ordlistan över internerade strängar. (Implementerad av Oren Tirosh.)

Optimeringar

  • Skapandet av nya klassinstanser har gjorts mycket snabbare; de är nu snabbare än klassiska klasser!

  • Metoden sort() för listobjekt har skrivits om i stor utsträckning av Tim Peters, och implementeringen är betydligt snabbare.

  • Multiplikation av stora långa heltal är nu mycket snabbare tack vare en implementering av Karatsuba-multiplikation, en algoritm som skalar bättre än O(n2) som krävs för grundskolans multiplikationsalgoritm. (Ursprunglig patch av Christopher A. Craig, och väsentligt omarbetad av Tim Peters)

  • Opkoden SET_LINENO är nu borta. Detta kan ge en liten hastighetsökning, beroende på din kompilators idiosynkrasier. Se avsnitt Övriga ändringar och korrigeringar för en längre förklaring. (Borttagen av Michael Hudson.)

  • xrange()-objekt har nu sin egen iterator, vilket gör for i in xrange(n) något snabbare än for i in range(n). (Patch av Raymond Hettinger.)

  • Ett antal små omarrangemang har gjorts i olika hotspots för att förbättra prestandan, t.ex. inlining av en funktion eller borttagning av viss kod. (Implementerat mestadels av GvR, men många människor har bidragit med enskilda ändringar)

Nettoresultatet av 2.3-optimeringarna är att Python 2.3 kör pystone-riktmärket cirka 25% fsnabbare än Python 2.2.

Nya, förbättrade och utfasade moduler

Som vanligt fick Pythons standardbibliotek ett antal förbättringar och buggfixar. Här är en partiell lista över de mest anmärkningsvärda ändringarna, sorterade alfabetiskt efter modulnamn. Se filen Misc/NEWS i källträdet för en mer komplett lista över ändringar, eller titta igenom CVS-loggarna för alla detaljer.

  • Modulen array har nu stöd för matriser med Unicode-tecken som använder formattecknet 'u'. Arrayer stöder nu också användning av tilldelningsoperatorn += för att lägga till innehållet i en annan array och tilldelningsoperatorn *= för att upprepa en array. (Bidrag från Jason Orendorff.)

  • Modulen bsddb har ersatts av version 4.1.6 av paketet PyBSDDB, vilket ger ett mer komplett gränssnitt till transaktionsfunktionerna i BerkeleyDB-biblioteket.

    Den gamla versionen av modulen har bytt namn till bsddb185 och byggs inte längre automatiskt; du måste redigera Modules/Setup för att aktivera den. Observera att det nya bsddb-paketet är avsett att vara kompatibelt med den gamla modulen, så var noga med att rapportera buggar om du upptäcker några inkompatibiliteter. När du uppgraderar till Python 2.3, om den nya tolken är kompilerad med en ny version av det underliggande BerkeleyDB-biblioteket, kommer du nästan säkert att behöva konvertera dina databasfiler till den nya versionen. Du kan göra detta ganska enkelt med de nya skripten db2pickle.py och pickle2db.py som du hittar i distributionens katalog Tools/scripts. Om du redan har använt PyBSDDB-paketet och importerat det som bsddb3, måste du ändra dina import-satser så att du importerar det som bsddb.

  • Den nya modulen bz2 är ett gränssnitt till datakomprimeringsbiblioteket bz2. bz2-komprimerad data är vanligtvis mindre än motsvarande zlib-komprimerad data. (Bidrag från Gustavo Niemeyer.)

  • En uppsättning standardtyper för datum/tid har lagts till i den nya modulen datetime. Se följande avsnitt för mer information.

  • Klassen Distutils Extension stöder nu ett extra konstruktörsargument med namnet depends för att lista ytterligare källfiler som ett tillägg är beroende av. Detta låter Distutils kompilera om modulen om någon av de beroende filerna ändras. Om till exempel sampmodule.c innehåller header-filen sample.h, skulle du skapa Extension-objektet så här:

    ext = Extension("samp",
                    sources=["sampmodule.c"],
                    depends=["sample.h"])
    

    Modifiering av sample.h skulle då leda till att modulen kompileras om. (Bidrag från Jeremy Hylton.)

  • Andra mindre ändringar i Distutils: det kontrollerar nu för miljövariablerna CC, CFLAGS, CPP, LDFLAGS och CPPFLAGS, och använder dem för att åsidosätta inställningarna i Pythons konfiguration (bidrag från Robert Weber).

  • Tidigare sökte modulen doctest bara efter testfall i dokumentsträngarna för offentliga metoder och funktioner, men nu undersöker den även privata metoder och funktioner. Funktionen DocTestSuite() skapar ett unittest.TestSuite-objekt från en uppsättning doctest-tester.

  • Den nya funktionen gc.get_referents(object) returnerar en lista över alla objekt som refereras till av object.

  • Modulen getopt har fått en ny funktion, gnu_getopt(), som stöder samma argument som den befintliga funktionen getopt() men som använder GNU-stils skanningsläge. Den befintliga getopt() slutar bearbeta alternativ så snart ett argument som inte är ett alternativ påträffas, men i GNU-stil fortsätter bearbetningen, vilket innebär att alternativ och argument kan blandas. Till exempel:

    >>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v')
    ([('-f', 'filename')], ['output', '-v'])
    >>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v')
    ([('-f', 'filename'), ('-v', '')], ['output'])
    

    (Bidrag från Peter Åstrand.)

  • Modulerna grp, pwd och resource returnerar nu förbättrade tuples:

    >>> import grp
    >>> g = grp.getgrnam('amk')
    >>> g.gr_name, g.gr_gid
    ('amk', 500)
    
  • Modulen gzip kan nu hantera filer som överstiger 2 GiB.

  • Den nya modulen heapq innehåller en implementation av en heap-köalgoritm. En heap är en array-liknande datastruktur som håller objekt i en delvis sorterad ordning så att, för varje index k, heap[k] <= heap[2*k+1] och heap[k] <= heap[2*k+2]. Detta gör att det går snabbt att ta bort det minsta objektet, och att infoga ett nytt objekt samtidigt som heap-egenskapen bibehålls är O(log n). (Se https://xlinux.nist.gov/dads//HTML/priorityque.html för mer information om datastrukturen för prioritetsköer)

    Modulen heapq tillhandahåller funktionerna heappush() och heappop() för att lägga till och ta bort objekt samtidigt som heap-egenskapen bibehålls ovanpå någon annan föränderlig Python-sekvenstyp. Här är ett exempel som använder en Python-lista:

    >>> import heapq
    >>> heap = []
    >>> for item in [3, 7, 5, 11, 1]:
    ...    heapq.heappush(heap, item)
    ...
    >>> heap
    [1, 3, 5, 11, 7]
    >>> heapq.heappop(heap)
    1
    >>> heapq.heappop(heap)
    3
    >>> heap
    [5, 7, 11]
    

    (Bidrag från Kevin O’Connor.)

  • Den integrerade utvecklingsmiljön IDLE har uppdaterats med hjälp av koden från IDLEfork-projektet (https://idlefork.sourceforge.net). Den mest anmärkningsvärda funktionen är att koden som utvecklas nu körs i en underprocess, vilket innebär att det inte längre finns något behov av manuella reload()-operationer. IDLE:s kärnkod har införlivats i standardbiblioteket som paketet idlelib.

  • Modulen imaplib har nu stöd för IMAP över SSL. (Bidrag från Piers Lauder och Tino Lange.)

  • itertools innehåller ett antal användbara funktioner för användning med iteratorer, inspirerade av olika funktioner som tillhandahålls av språken ML och Haskell. Till exempel returnerar itertools.ifilter(predicate, iterator) alla element i iteratorn för vilka funktionen predicate() returnerar True, och itertools.repeat(obj, N) returnerar obj N gånger. Det finns ett antal andra funktioner i modulen; se paketets referensdokumentation för detaljer. (Bidrag från Raymond Hettinger.)

  • Två nya funktioner i modulen math, degrees(rads) och radians(degs), konverterar mellan radianer och grader. Andra funktioner i modulen math, t.ex. math.sin() och math.cos(), har alltid krävt ingångsvärden som mätts i radianer. Dessutom lades ett valfritt base-argument till i math.log() för att göra det enklare att beräkna logaritmer för andra baser än e och 10. (Bidrag från Raymond Hettinger.)

  • Flera nya POSIX-funktioner (getpgid(), killpg(), lchown(), loadavg(), major(), makedev(), minor() och mknod()) har lagts till i modulen posix som ligger till grund för modulen os. (Bidrag från Gustavo Niemeyer, Geert Jansen och Denis S. Otkidach)

  • I modulen os kan funktionerna i *stat()-familjen nu rapportera bråkdelar av en sekund i en tidsstämpel. Sådana tidsstämplar representeras som flyttal, liknande det värde som returneras av time.time().

    Under testningen upptäcktes att vissa program inte fungerar om tidsstämplarna är flyttal. För kompatibilitet, när du använder tuple-gränssnittet i stat_result kommer tidsstämplar att representeras som heltal. Vid användning av namngivna fält (en funktion som först introducerades i Python 2.2) representeras tidsstämplar fortfarande som heltal, såvida inte os.stat_float_times() anropas för att aktivera returvärden med flyttal:

    >>> os.stat("/tmp").st_mtime
    1034791200
    >>> os.stat_float_times(True)
    >>> os.stat("/tmp").st_mtime
    1034791200.6335014
    

    I Python 2.4 kommer standardinställningen att ändras till att alltid returnera floats.

    Programutvecklare bör endast aktivera den här funktionen om alla deras bibliotek fungerar korrekt när de konfronteras med tidsstämplar med flyttal eller om de använder tuple-API:et. Om funktionen används bör den aktiveras på applikationsnivå istället för att försöka aktivera den för varje enskild användning.

  • Modulen optparse innehåller en ny analysator för kommandoradsargument som kan konvertera alternativvärden till en viss Python-typ och automatiskt generera ett användningsmeddelande. Se följande avsnitt för mer information.

  • Den gamla och aldrig dokumenterade modulen linuxaudiodev har utgått och en ny version med namnet ossaudiodev har lagts till. Modulen döptes om eftersom OSS-ljuddrivrutinerna kan användas på andra plattformar än Linux, och gränssnittet har också snyggats till och uppdaterats på olika sätt. (Bidrag från Greg Ward och Nicholas FitzRoy-Dale.)

  • Den nya modulen platform innehåller ett antal funktioner som försöker fastställa olika egenskaper hos den plattform du kör på. Det finns funktioner för att få fram arkitektur, CPU-typ, Windows OS-version och till och med Linux-distributionsversion. (Bidrag från Marc-André Lemburg.)

  • De parserobjekt som tillhandahålls av modulen pyexpat kan nu buffra teckendata, vilket resulterar i färre anrop till din teckendatahanterare och därmed snabbare prestanda. Om parserobjektets attribut buffer_text sätts till True aktiveras buffring.

  • Funktionen sample(population, k) har lagts till i modulen random. population är en sekvens eller ett xrange-objekt som innehåller elementen i en population, och sample() väljer k element från populationen utan att ersätta valda element. k kan vara vilket värde som helst upp till len(population). Till exempel:

    >>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn']
    >>> random.sample(days, 3)      # Choose 3 elements
    ['St', 'Sn', 'Th']
    >>> random.sample(days, 7)      # Choose 7 elements
    ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn']
    >>> random.sample(days, 7)      # Choose 7 again
    ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']
    >>> random.sample(days, 8)      # Can't choose eight
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "random.py", line 414, in sample
          raise ValueError, "sample larger than population"
    ValueError: sample larger than population
    >>> random.sample(xrange(1,10000,2), 10)   # Choose ten odd nos. under 10000
    [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]
    

    Modulen random använder nu en ny algoritm, Mersenne Twister, som är implementerad i C. Den är snabbare och mer välstuderad än den tidigare algoritmen.

    (Alla ändringar har gjorts av Raymond Hettinger.)

  • Modulen readline har också fått ett antal nya funktioner: get_history_item(), get_current_history_length() och redisplay().

  • Modulerna rexec och Bastion har dödförklarats och försök att importera dem kommer att misslyckas med ett RuntimeError. Klasser i ny stil ger nya sätt att bryta sig ur den begränsade exekveringsmiljön som rexec ger, och ingen har intresse av att fixa dem eller tid att göra det. Om du har program som använder rexec, skriv om dem så att de använder något annat.

    (Att hålla sig till Python 2.2 eller 2.1 kommer inte att göra dina applikationer säkrare eftersom det finns kända buggar i modulen rexec i dessa versioner. För att upprepa: om du använder rexec, sluta använda den omedelbart)

  • Modulen rotor har utgått eftersom den algoritm som används för kryptering inte anses vara säker. Om du behöver kryptering, använd en av de många AES Python-moduler som finns tillgängliga separat.

  • Modulen shutil har utökats med funktionen move(src, dest) som rekursivt flyttar en fil eller katalog till en ny plats.

  • Stöd för mer avancerad POSIX-signalhantering lades till i signal men togs sedan bort igen eftersom det visade sig omöjligt att få det att fungera tillförlitligt på olika plattformar.

  • Modulen socket har nu stöd för timeouts. Du kan anropa metoden settimeout(t) på ett socket-objekt för att ställa in en timeout på t sekunder. Efterföljande socket-operationer som tar längre tid än t sekunder att slutföra kommer att avbrytas och ge upphov till ett socket.timeout-undantag.

    Den ursprungliga implementeringen av timeout gjordes av Tim O’Malley. Michael Gilfix integrerade den i Python socket-modulen och ledde den genom en lång granskning. Efter att koden hade checkats in skrev Guido van Rossum om delar av den. (Detta är ett bra exempel på en utvecklingsprocess som bygger på samarbete)

  • På Windows levereras nu modulen socket med stöd för SSL (Secure Sockets Layer).

  • Värdet på C PYTHON_API_VERSION-makrot är nu exponerat på Python-nivå som sys.api_version. Det aktuella undantaget kan rensas genom att anropa den nya sys.exc_clear()-funktionen.

  • Den nya modulen tarfile gör det möjligt att läsa från och skriva till arkivfiler i formatet tar. (Bidrag från Lars Gustäbel.)

  • Den nya modulen textwrap innehåller funktioner för ombrytning av strängar som innehåller textstycken. Funktionen wrap(text, width) tar en sträng och returnerar en lista som innehåller texten uppdelad i rader med högst den valda bredden. Funktionen fill(text, width) returnerar en enda sträng, omformaterad för att passa in i rader som inte är längre än den valda bredden. (Som du kan gissa bygger fill()wrap(). Till exempel:

    >>> import textwrap
    >>> paragraph = "Not a whit, we defy augury: ... more text ..."
    >>> textwrap.wrap(paragraph, 60)
    ["Not a whit, we defy augury: there's a special providence in",
     "the fall of a sparrow. If it be now, 'tis not to come; if it",
     ...]
    >>> print textwrap.fill(paragraph, 35)
    Not a whit, we defy augury: there's
    a special providence in the fall of
    a sparrow. If it be now, 'tis not
    to come; if it be not to come, it
    will be now; if it be not now, yet
    it will come: the readiness is all.
    >>>
    

    Modulen innehåller också en TextWrapper-klass som faktiskt implementerar textombrytningsstrategin. Både klassen TextWrapper och funktionerna wrap() och fill() stöder ett antal ytterligare nyckelordsargument för att finjustera formateringen; se modulens dokumentation för mer information. (Bidrag från Greg Ward.)

  • Modulerna thread och threading har nu följeslagarmoduler, dummy_thread och dummy_threading, som ger en ”do-nothing”-implementering av thread-modulens gränssnitt för plattformar där trådar inte stöds. Avsikten är att förenkla trådmedvetna moduler (sådana som inte förlitar sig på trådar för att köras) genom att lägga följande kod högst upp:

    try:
        import threading as _threading
    except ImportError:
        import dummy_threading as _threading
    

    I det här exemplet används _threading som modulnamn för att klargöra att den modul som används inte nödvändigtvis är den faktiska modulen threading. Kod kan anropa funktioner och använda klasser i _threading oavsett om trådar stöds eller inte, vilket undviker ett if-slutsats och gör koden något tydligare. Den här modulen kommer inte på något magiskt sätt att få flertrådad kod att köras utan trådar; kod som väntar på att en annan tråd ska återvända eller göra något kommer helt enkelt att hänga sig för evigt.

  • Modulen time:s funktion strptime() har länge varit ett irritationsmoment eftersom den använder plattform C-bibliotekets implementation strptime(), och olika plattformar har ibland udda buggar. Brett Cannon bidrog med en portabel implementation som är skriven i ren Python och som bör bete sig identiskt på alla plattformar.

  • Den nya modulen timeit hjälper till att mäta hur lång tid det tar att exekvera bitar av Python-kod. Filen timeit.py kan köras direkt från kommandoraden, eller så kan modulens klass Timer importeras och användas direkt. Här är ett kort exempel som räknar ut om det är snabbare att konvertera en 8-bitars sträng till Unicode genom att lägga till en tom Unicode-sträng till den eller genom att använda funktionen unicode():

    import timeit
    
    timer1 = timeit.Timer('unicode("abc")')
    timer2 = timeit.Timer('"abc" + u""')
    
    # Run three trials
    print timer1.repeat(repeat=3, number=100000)
    print timer2.repeat(repeat=3, number=100000)
    
    # On my laptop this outputs:
    # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]
    # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]
    
  • Modulen Tix har fått olika buggfixar och uppdateringar för den aktuella versionen av Tix-paketet.

  • Modulen Tkinter fungerar nu med en trådaktiverad version av Tcl. Tcl:s trådmodell kräver att widgetar endast kan nås från den tråd i vilken de skapades; åtkomst från en annan tråd kan orsaka panik i Tcl. För vissa Tcl-gränssnitt kommer Tkinter nu automatiskt att undvika detta när en widget nås från en annan tråd genom att marshalla ett kommando, skicka det till rätt tråd och vänta på resultatet. Andra gränssnitt kan inte hanteras automatiskt men Tkinter kommer nu att ge upphov till ett undantag vid sådan åtkomst så att du åtminstone kan ta reda på problemet. Se https://mail.python.org/pipermail/python-dev/2002-December/031107.html för en mer detaljerad förklaring av denna förändring. (Implementerad av Martin von Löwis.)

  • Anrop av Tcl-metoder via _tkinter returnerar inte längre bara strängar. Istället, om Tcl returnerar andra objekt konverteras dessa objekt till sin Python-ekvivalent, om en sådan finns, eller omsluts med ett _tkinter.Tcl_Obj-objekt om ingen Python-ekvivalent finns. Detta beteende kan kontrolleras genom metoden wantobjects() för tkapp-objekt.

    När _tkinter används genom modulen Tkinter (vilket de flesta Tkinter-applikationer gör), är den här funktionen alltid aktiverad. Det bör inte orsaka kompatibilitetsproblem, eftersom Tkinter alltid konverterar strängresultat till Python-typer där det är möjligt.

    Om några inkompatibiliteter upptäcks kan det gamla beteendet återställas genom att variabeln wantobjects i modulen Tkinter sätts till false innan det första objektet tkapp skapas.

    import Tkinter
    Tkinter.wantobjects = 0
    

    Eventuella avbrott som orsakas av denna ändring ska rapporteras som en bugg.

  • Modulen UserDict har en ny klass DictMixin som definierar alla ordboksmetoder för klasser som redan har ett minimalt mappningsgränssnitt. Detta förenklar avsevärt skrivandet av klasser som behöver vara utbytbara mot ordböcker, såsom klasserna i modulen shelve.

    Om du lägger till mix-in som en superklass får du det fullständiga ordboksgränssnittet när klassen definierar __getitem__(), __setitem__(), __delitem__() och keys(). Till exempel:

    >>> import UserDict
    >>> class SeqDict(UserDict.DictMixin):
    ...     """Dictionary lookalike implemented with lists."""
    ...     def __init__(self):
    ...         self.keylist = []
    ...         self.valuelist = []
    ...     def __getitem__(self, key):
    ...         try:
    ...             i = self.keylist.index(key)
    ...         except ValueError:
    ...             raise KeyError
    ...         return self.valuelist[i]
    ...     def __setitem__(self, key, value):
    ...         try:
    ...             i = self.keylist.index(key)
    ...             self.valuelist[i] = value
    ...         except ValueError:
    ...             self.keylist.append(key)
    ...             self.valuelist.append(value)
    ...     def __delitem__(self, key):
    ...         try:
    ...             i = self.keylist.index(key)
    ...         except ValueError:
    ...             raise KeyError
    ...         self.keylist.pop(i)
    ...         self.valuelist.pop(i)
    ...     def keys(self):
    ...         return list(self.keylist)
    ...
    >>> s = SeqDict()
    >>> dir(s)      # See that other dictionary methods are implemented
    ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__',
     '__init__', '__iter__', '__len__', '__module__', '__repr__',
     '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems',
     'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem',
     'setdefault', 'update', 'valuelist', 'values']
    

    (Bidrag från Raymond Hettinger.)

  • DOM-implementationen i xml.dom.minidom kan nu generera XML-utdata i en viss kodning genom att tillhandahålla ett valfritt kodningsargument till metoderna toxml() och toprettyxml() för DOM-noder.

  • Modulen xmlrpclib har nu stöd för ett XML-RPC-tillägg för hantering av nil-datavärden, t.ex. Pythons None. Nil-värden stöds alltid vid unmarshalling av ett XML-RPC-svar. För att generera begäranden som innehåller None måste du ange ett true-värde för parametern allow_none när du skapar en Marshaller-instans.

  • Den nya DocXMLRPCServer-modulen gör det möjligt att skriva självdokumenterande XML-RPC-servrar. Kör den i demoläge (som ett program) för att se hur den fungerar. Genom att peka webbläsaren mot RPC-servern produceras dokumentation i pydoc-stil; genom att peka xmlrpclib mot servern kan man anropa de faktiska metoderna. (Bidrag från Brian Quinlan.)

  • Stöd för internationaliserade domännamn (RFC 3454, 3490, 3491 och 3492) har lagts till. Kodningen ”idna” kan användas för att konvertera mellan ett Unicode-domännamn och den ASCII-kompatibla kodningen (ACE) av det namnet.

    >{}>{}> u"www.Alliancefrançaise.nu".encode("idna")
    'www.xn--alliancefranaise-npb.nu'
    

    Modulen socket har också utökats för att på ett transparent sätt konvertera Unicode-värdnamn till ACE-versionen innan de skickas till C-biblioteket. Moduler som hanterar värdnamn såsom httplib och ftplib) stöder också Unicode-värdnamn; httplib skickar också HTTP Host-rubriker med ACE-versionen av domännamnet. urllib stöder Unicode-URL:er med icke-ASCII-värdnamn så länge som path-delen av URL:en endast är ASCII.

    För att implementera denna ändring har modulen stringprep, verktyget mkstringprep och kodningen punycode lagts till.

Datum/Tid Typ

Datum- och tidstyper som lämpar sig för att uttrycka tidsstämplar har lagts till i modulen datetime. Typerna stöder inte olika kalendrar eller många andra avancerade funktioner, utan håller sig bara till grunderna för att representera tid.

De tre primära typerna är: date, som representerar en dag, månad och år; time, som består av timme, minut och sekund; och datetime, som innehåller alla attribut från både date och time. Det finns också en klass timedelta som representerar skillnader mellan två tidpunkter, och tidszonlogik implementeras av klasser som ärver från den abstrakta klassen tzinfo.

Du kan skapa instanser av date och time antingen genom att ange nyckelordsargument till lämplig konstruktör, t.ex. datetime.date(year=1972, month=10, day=15), eller genom att använda en av ett antal klassmetoder. Exempelvis ger klassmetoden today() det aktuella lokala datumet.

När de väl har skapats är alla instanser av date/time-klasserna oföränderliga. Det finns ett antal metoder för att producera formaterade strängar från objekt:

>>> import datetime
>>> now = datetime.datetime.now()
>>> now.isoformat()
'2002-12-30T21:27:03.994956'
>>> now.ctime()  # Only available on date, datetime
'Mon Dec 30 21:27:03 2002'
>>> now.strftime('%Y %d %b')
'2002 30 Dec'

Med metoden replace() kan du ändra ett eller flera fält i en instans av date eller datetime och returnera en ny instans:

>>> d = datetime.datetime.now()
>>> d
datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)
>>> d.replace(year=2001, hour = 12)
datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)
>>>

Instanser kan jämföras, hashas och konverteras till strängar (resultatet är detsamma som för isoformat()). instanser av date och datetime kan subtraheras från varandra och adderas till instanser av timedelta. Den största saknade funktionen är att det inte finns något standardbiblioteksstöd för att analysera strängar och få tillbaka en date eller datetime.

För mer information, se modulens referensdokumentation. (Bidrag från Tim Peters.)

Optparse-modulen

Modulen getopt ger en enkel analys av kommandoradsargument. Den nya modulen optparse (som ursprungligen hette Optik) ger en mer detaljerad tolkning av kommandoraden som följer Unix-konventionerna, skapar automatiskt utdata för --help och kan utföra olika åtgärder för olika alternativ.

Du börjar med att skapa en instans av OptionParser och tala om för den vilka alternativ ditt program har.

import sys
from optparse import OptionParser

op = OptionParser()
op.add_option('-i', '--input',
              action='store', type='string', dest='input',
              help='set input filename')
op.add_option('-l', '--length',
              action='store', type='int', dest='length',
              help='set maximum length of output')

Parsning av en kommandorad görs sedan genom att anropa metoden parse_args().

options, args = op.parse_args(sys.argv[1:])
skriv ut alternativ
skriv ut args

Detta returnerar ett objekt som innehåller alla alternativvärden och en lista med strängar som innehåller de återstående argumenten.

Att anropa skriptet med de olika argumenten fungerar nu som du förväntar dig att det ska göra. Observera att argumentet length automatiskt konverteras till ett heltal.

$ ./python opt.py -i data arg1
<Värden vid 0x400cad4c: {'input': 'data', 'length': None}>
['arg1']
$ ./python opt.py --input=data --length=4
<Värden på 0x400cad2c: {'input': 'data', 'length': 4}>
[]
$

Hjälpmeddelandet genereras automatiskt åt dig:

$ ./python opt.py --hjälp
användning: opt.py [alternativ]

alternativ:
  -h, --help visa detta hjälpmeddelande och avsluta
  -iINPUT, --input=INPUT
                        ange filnamn för inmatning
  -lLENGTH, --längd=LÄNGD
                        anger maximal längd på utdata
$

Se modulens dokumentation för mer information.

Optik har skrivits av Greg Ward, med förslag från läsarna av Getopt SIG.

Pymalloc: En specialiserad objektallokering

Pymalloc, en specialiserad objektallokator skriven av Vladimir Marangozov, var en funktion som lades till i Python 2.1. Pymalloc är tänkt att vara snabbare än systemets malloc() och att ha mindre minnesoverhead för allokeringsmönster som är typiska för Python-program. Allokatorn använder C:s malloc()-funktion för att få stora minnespooler och uppfyller sedan mindre minnesförfrågningar från dessa pooler.

I 2.1 och 2.2 var pymalloc en experimentell funktion och var inte aktiverad som standard; du var tvungen att uttryckligen aktivera den när du kompilerade Python genom att ange --with-pymalloc-alternativet till configure-skriptet. I 2.3 har pymalloc förbättrats ytterligare och är nu aktiverat som standard; du måste ange --without-pymalloc för att inaktivera det.

Denna ändring är transparent för kod skriven i Python, men pymalloc kan avslöja buggar i C-tillägg. Författare till C-tilläggsmoduler bör testa sin kod med pymalloc aktiverat, eftersom viss felaktig kod kan orsaka kärndumpar vid körning.

Det finns ett särskilt vanligt fel som orsakar problem. Det finns ett antal 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 kan du få en kärndump. Till exempel, om minne allokerades med PyObject_Malloc(), måste det frigöras med PyObject_Free(), inte free(). Några moduler som ingår i Python drabbades av detta och måste åtgärdas; utan tvekan finns det fler tredjepartsmoduler som kommer att ha samma problem.

Som en del av denna förändring har de förvirrande många gränssnitten för allokering av minne konsoliderats till två API-familjer. Minne som allokerats med den ena familjen får inte manipuleras med funktioner från den andra familjen. Det finns en familj för allokering av minnesbitar och en annan familj med funktioner som är särskilt avsedda för allokering av Python-objekt.

Tack vare mycket arbete av Tim Peters har pymalloc i 2.3 också felsökningsfunktioner för att fånga upp minnesöverskrivningar och dubbla frees i både tilläggsmoduler och i själva tolken. För att aktivera detta stöd, kompilera en felsökningsversion av Python-tolken genom att köra configure med --with-pydebug.

För att hjälpa författare av tillägg distribueras en header-fil Misc/pymemcompat.h med källan till Python 2.3 som gör det möjligt för Python-tillägg att använda 2.3-gränssnitten för minnesallokering när de kompilerar mot alla versioner av Python sedan 1.5.2. Du kopierar filen från Pythons källdistribution och buntar den med källan till ditt tillägg.

Se även

https://hg.python.org/cpython/file/default/Objects/obmalloc.c

För fullständiga detaljer om pymalloc-implementeringen, se kommentarerna högst upp i filen Objects/obmalloc.c i Pythons källkod. Ovanstående länk pekar på filen i python.org SVN-webbläsaren.

Ändringar i Build och C API

Ändringar i Pythons byggprocess och i C API inkluderar:

  • Implementationen av cykeldetektering som används av skräpinsamlingen har visat sig vara stabil, så den har nu gjorts obligatorisk. Du kan inte längre kompilera Python utan det, och --with-cycle-gc till configure har tagits bort.

  • Python kan nu eventuellt byggas som ett delat bibliotek (libpython2.3.so) genom att ange --enable-shared när Pythons configure-skript körs. (Bidrag från Ondrej Palkovsky.)

  • Makrot DL_EXPORT och DL_IMPORT är nu föråldrade. Initialiseringsfunktioner för Python-tilläggsmoduler bör nu deklareras med det nya makrot PyMODINIT_FUNC, medan Python-kärnan i allmänhet kommer att använda makrot PyAPI_FUNC och PyAPI_DATA.

  • Tolken kan kompileras utan några dokumentsträngar för de inbyggda funktionerna och modulerna genom att ange --without-doc-strings till configure-skriptet. Detta gör Pythons körbara program ca 10% smaller, men innebär också att du inte kan få hjälp med Pythons inbyggda funktioner. (Bidrag från Gustavo Niemeyer.)

  • Makrot PyArg_NoArgs() är nu föråldrat, och kod som använder det bör ändras. För Python 2.2 och senare kan metoddefinitionstabellen ange METH_NOARGS-flaggan, vilket signalerar att det inte finns några argument, och argumentkontrollen kan då tas bort. Om kompatibilitet med Python-versioner före 2.2 är viktig, kan koden använda PyArg_ParseTuple(args, "") istället, men detta kommer att vara långsammare än att använda METH_NOARGS.

  • PyArg_ParseTuple() accepterar nya formattecken för olika storlekar av osignerade heltal: B för unsigned char, H för unsigned short int, I för unsigned int, och K för unsigned long long.

  • En ny funktion, PyObject_DelItemString(mappning, char *nyckel) lades till som kortform för PyObject_DelItem(mappning, PyString_New(nyckel)).

  • File-objekt hanterar nu sin interna strängbuffert annorlunda och ökar den exponentiellt när det behövs. Detta resulterar i att benchmarktesterna i Lib/test/test_bufio.py går betydligt snabbare (från 57 sekunder till 1,7 sekunder, enligt en mätning).

  • Det är nu möjligt att definiera klass- och statiska metoder för en C-tilläggstyp genom att ange antingen METH_CLASS- eller METH_STATIC-flaggorna i en metods PyMethodDef-struktur.

  • Python innehåller nu en kopia av Expat XML-parserns källkod, vilket gör att man inte längre är beroende av en systemversion eller lokal installation av Expat.

  • Om du dynamiskt allokerar typobjekt i ditt tillägg bör du vara medveten om en ändring i reglerna för attributen __module__ och __name__. Sammanfattningsvis bör du se till att typens dictionary innehåller nyckeln '__module__'; att göra modulnamnet till den del av typnamnet som leder fram till den sista perioden kommer inte längre att ha önskad effekt. För mer detaljer, läs API-referensdokumentationen eller källan.

Hamnspecifika ändringar

Stöd för en portning till IBM:s OS/2 med hjälp av EMX runtime-miljön slogs samman med Pythons huvudkällträd. EMX är ett POSIX-emuleringslager över OS/2-systemets API:er. Python-portningen för EMX försöker stödja alla POSIX-liknande funktioner som EMX runtime erbjuder och lyckas för det mesta; fork() och fcntl() begränsas av det underliggande emuleringslagrets begränsningar. Standardporten för OS/2, som använder IBM:s Visual Age-kompilator, fick också stöd för skiftlägeskänslig importsemantik som en del av integrationen av EMX-porten i CVS. (Bidrag från Andrew MacIntyre.)

På MacOS har de flesta verktygslådemoduler försetts med svaga länkar för att förbättra bakåtkompatibiliteten. Detta innebär att moduler inte längre misslyckas med att laddas om en enda rutin saknas i den aktuella OS-versionen. Istället kommer anrop av den saknade rutinen att ge upphov till ett undantag. (Bidrag från Jack Jansen.)

RPM-specifikationsfilerna, som finns i katalogen Misc/RPM/ i Python-källdistributionen, uppdaterades för 2.3. (Bidrag från Sean Reifschneider.)

Andra nya plattformar som nu stöds av Python är AtheOS (http://www.atheos.cx/), GNU/Hurd och OpenVMS.

Övriga ändringar och korrigeringar

Som vanligt fanns det en massa andra förbättringar och buggfixar utspridda i hela källträdet. En sökning genom CVS-ändringsloggarna visar att det fanns 523 patchar tillämpade och 514 buggar fixade mellan Python 2.2 och 2.3. Båda siffrorna är sannolikt underskattningar.

Några av de mer anmärkningsvärda förändringarna är:

  • Om miljövariabeln PYTHONINSPECT är inställd kommer Python-tolken att gå till den interaktiva prompten efter att ha kört ett Python-program, som om Python hade anropats med alternativet -i. Miljövariabeln kan sättas innan Python-tolken körs, eller så kan den sättas av Python-programmet som en del av dess exekvering.

  • Skriptet regrtest.py erbjuder nu ett sätt att tillåta ”alla resurser utom foo” Ett resursnamn som skickas till alternativet -u kan nu förses med ett bindestreck ('-') för att betyda ”ta bort den här resursen” Till exempel kan alternativet ”-uall,-bsddb” användas för att aktivera användningen av alla resurser utom bsddb.

  • De verktyg som används för att bygga dokumentationen fungerar nu under Cygwin såväl som Unix.

  • Operativkoden SET_LINENO har tagits bort. Förr i tiden behövdes denna opcode för att producera radnummer i spårningar och stödja spårningsfunktioner (för t.ex. pdb). Sedan Python 1.5 har radnumren i tracebacks beräknats med hjälp av en annan mekanism som fungerar med ”python -O”. För Python 2.3 har Michael Hudson implementerat ett liknande system för att avgöra när trace-funktionen ska anropas, vilket helt tar bort behovet av SET_LINENO.

    Det skulle vara svårt att upptäcka någon skillnad i Python-kod, bortsett från en liten hastighetsökning när Python körs utan -O.

    C-tillägg som använder fältet f_lineno i frame-objekt bör istället anropa PyCode_Addr2Line(f->f_code, f->f_lasti). Detta kommer att ha den extra effekten att koden fungerar som önskat under ”python -O” i tidigare versioner av Python.

    En fiffig ny funktion är att spårningsfunktioner nu kan tilldelas attributet f_lineno för frame-objekt, vilket ändrar vilken rad som kommer att exekveras härnäst. Ett jump-kommando har lagts till i pdb-felsökaren för att dra nytta av denna nya funktion. (Implementerat av Richie Hindle.)

Portning till Python 2.3

I detta avsnitt listas tidigare beskrivna ändringar som kan kräva ändringar i din kod:

  • yield är nu alltid ett nyckelord; om det används som variabelnamn i din kod måste du välja ett annat namn.

  • För strängar X och Y fungerar nu X i Y om X är mer än ett tecken lång.

  • Typkonstruktören int() returnerar nu ett långt heltal istället för att ge upphov till ett OverflowError när en sträng eller ett flyttal är för stort för att rymmas i ett heltal.

  • Om du har Unicode-strängar som innehåller 8-bitars tecken måste du ange filens kodning (UTF-8, Latin-1 eller något annat) genom att lägga till en kommentar längst upp i filen. Se avsnitt PEP 263: Kodning av källkod för mer information.

  • Anrop av Tcl-metoder via _tkinter returnerar inte längre bara strängar. Istället, om Tcl returnerar andra objekt konverteras dessa objekt till sin Python-ekvivalent, om en sådan finns, eller omsluts med ett _tkinter.Tcl_Obj-objekt om ingen Python-ekvivalent finns.

  • Stora oktal- och hex-literaler som 0xffffffff utlöser nu en FutureWarning. För närvarande lagras de som 32-bitars tal och resulterar i ett negativt värde, men i Python 2.4 kommer de att bli positiva långa heltal.

    Det finns några sätt att åtgärda denna varning. Om du verkligen behöver ett positivt tal, lägg bara till ett L i slutet av det bokstavliga talet. Om du försöker få ett 32-bitars heltal med låga bitar inställda och tidigare har använt ett uttryck som ~(1 << 31), är det förmodligen tydligast att börja med alla bitar inställda och rensa de önskade övre bitarna. Om du till exempel bara vill rensa den översta biten (bit 31) kan du skriva 0xffffffffffL &~(1L<<31).

  • Du kan inte längre inaktivera påståenden genom att tilldela till __debug__.

  • Distutils setup()-funktion har fått flera nya nyckelordsargument som depends. Gamla versioner av Distutils kommer att avbrytas om okända nyckelord skickas. En lösning är att kontrollera om den nya funktionen get_distutil_options() finns i din setup.py och endast använda de nya nyckelorden med en version av Distutils som stöder dem:

    from distutils import core
    
    kw = {'sources': 'foo.c', ...}
    if hasattr(core, 'get_distutil_options'):
        kw['depends'] = ['foo.h']
    ext = Extension(**kw)
    
  • Att använda None som variabelnamn kommer nu att resultera i en SyntaxWarning-varning.

  • Namn på tilläggstyper som definieras av de moduler som ingår i Python innehåller nu modulen och en '.' framför typnamnet.

Tack till

Författaren vill tacka följande personer för förslag, korrigeringar och hjälp med olika utkast till denna artikel: Jeff Bauer, Simon Brunning, Brett Cannon, Michael Chermside, Andrew Dalke, Scott David Daniels, Fred L. Drake, Jr, David Fraser, Kelly Gerber, Raymond Hettinger, Michael Hudson, Chris Lambert, Detlef Lannert, Martin von Löwis, Andrew MacIntyre, Lalo Martins, Chad Netzer, Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, Francesco Ricciardi, Vinay Sajip, Neil Schemenauer, Roman Suzi, Jason Tishler, Just van Rossum.