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 try
…finally
-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 då 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 ettImportError
-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 innansys.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
ochFalse
lades till tillsammans med den inbyggda typenbool
, 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 ettOverflowError
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 attisinstance(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 ochKeyError
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ärdetNone
.(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 modulentypes
) 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ändwarnings.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ösaPendingDeprecationWarning
.Att använda
None
som variabelnamn kommer nu att resultera i enSyntaxWarning
-varning. I en framtida version av Python kanNone
ä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 skrivafor line in file_obj
. Filobjekt har också ett nytt skrivskyddat attributencoding
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 funktionensys.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 avX in Y
där X och Y är strängar. Det har nu ändrats; X kan vara en sträng av valfri längd, ochX in Y
returnerarTrue
om X är en delsträng av Y. Om X är den tomma strängen är resultatet alltidTrue
.>>> '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()
ochrstrip()
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()
ochendswith()
accepterar nu negativa tal för parametrarna start och end.En annan ny strängmetod är
zfill()
, som ursprungligen var en funktion i modulenstring
.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 änzfill()
.>>> '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 returneraTrue
för båda typerna av strängar. Det är en helt abstrakt typ, så du kan inte skapabasestring
-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örfor i in xrange(n)
något snabbare änfor 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 redigeraModules/Setup
för att aktivera den. Observera att det nyabsddb
-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 skriptendb2pickle.py
ochpickle2db.py
som du hittar i distributionens katalogTools/scripts
. Om du redan har använt PyBSDDB-paketet och importerat det sombsddb3
, måste du ändra dinaimport
-satser så att du importerar det sombsddb
.Den nya modulen
bz2
är ett gränssnitt till datakomprimeringsbiblioteket bz2. bz2-komprimerad data är vanligtvis mindre än motsvarandezlib
-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 exempelsampmodule.c
innehåller header-filensample.h
, skulle du skapaExtension
-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
ochCPPFLAGS
, 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. FunktionenDocTestSuite()
skapar ettunittest.TestSuite
-objekt från en uppsättningdoctest
-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 funktionengetopt()
men som använder GNU-stils skanningsläge. Den befintligagetopt()
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
ochresource
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]
ochheap[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 funktionernaheappush()
ochheappop()
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 paketetidlelib
.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 returneraritertools.ifilter(predicate, iterator)
alla element i iteratorn för vilka funktionenpredicate()
returnerarTrue
, ochitertools.repeat(obj, N)
returnerarobj
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)
ochradians(degs)
, konverterar mellan radianer och grader. Andra funktioner i modulenmath
, t.ex.math.sin()
ochmath.cos()
, har alltid krävt ingångsvärden som mätts i radianer. Dessutom lades ett valfritt base-argument till imath.log()
för att göra det enklare att beräkna logaritmer för andra baser äne
och10
. (Bidrag från Raymond Hettinger.)Flera nya POSIX-funktioner (
getpgid()
,killpg()
,lchown()
,loadavg()
,major()
,makedev()
,minor()
ochmknod()
) har lagts till i modulenposix
som ligger till grund för modulenos
. (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 avtime.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 inteos.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 namnetossaudiodev
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 attributbuffer_text
sätts tillTrue
aktiveras buffring.Funktionen
sample(population, k)
har lagts till i modulenrandom
. population är en sekvens eller ettxrange
-objekt som innehåller elementen i en population, ochsample()
väljer k element från populationen utan att ersätta valda element. k kan vara vilket värde som helst upp tilllen(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()
ochredisplay()
.Modulerna
rexec
ochBastion
har dödförklarats och försök att importera dem kommer att misslyckas med ettRuntimeError
. Klasser i ny stil ger nya sätt att bryta sig ur den begränsade exekveringsmiljön somrexec
ger, och ingen har intresse av att fixa dem eller tid att göra det. Om du har program som använderrexec
, 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änderrexec
, 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 funktionenmove(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 metodensettimeout(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 ettsocket.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å somsys.api_version
. Det aktuella undantaget kan rensas genom att anropa den nyasys.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. Funktionenwrap(text, width)
tar en sträng och returnerar en lista som innehåller texten uppdelad i rader med högst den valda bredden. Funktionenfill(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 byggerfill()
på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 klassenTextWrapper
och funktionernawrap()
ochfill()
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
ochthreading
har nu följeslagarmoduler,dummy_thread
ochdummy_threading
, som ger en ”do-nothing”-implementering avthread
-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 modulenthreading
. Kod kan anropa funktioner och använda klasser i_threading
oavsett om trådar stöds eller inte, vilket undviker ettif
-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 funktionstrptime()
har länge varit ett irritationsmoment eftersom den använder plattform C-bibliotekets implementationstrptime()
, 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. Filentimeit.py
kan köras direkt från kommandoraden, eller så kan modulens klassTimer
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 funktionenunicode()
: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 kommerTkinter
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 menTkinter
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 metodenwantobjects()
förtkapp
-objekt.När
_tkinter
används genom modulenTkinter
(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 modulenTkinter
sätts till false innan det första objektettkapp
skapas.import Tkinter Tkinter.wantobjects = 0
Eventuella avbrott som orsakas av denna ändring ska rapporteras som en bugg.
Modulen
UserDict
har en ny klassDictMixin
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 modulenshelve
.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__()
ochkeys()
. 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 metodernatoxml()
ochtoprettyxml()
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. PythonsNone
. Nil-värden stöds alltid vid unmarshalling av ett XML-RPC-svar. För att generera begäranden som innehållerNone
måste du ange ett true-värde för parametern allow_none när du skapar enMarshaller
-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åsomhttplib
ochftplib
) stöder också Unicode-värdnamn;httplib
skickar också HTTPHost
-rubriker med ACE-versionen av domännamnet.urllib
stöder Unicode-URL:er med icke-ASCII-värdnamn så länge sompath
-delen av URL:en endast är ASCII.För att implementera denna ändring har modulen
stringprep
, verktygetmkstringprep
och kodningenpunycode
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.
För att allokera och frigöra en oansenlig bit minne använder du ”raw memory”-familjen:
PyMem_Malloc()
,PyMem_Realloc()
ochPyMem_Free()
.Familjen ”object memory” är gränssnittet till pymalloc-funktionen som beskrivs ovan och är inriktad på ett stort antal ”små” allokeringar:
PyObject_Malloc()
,PyObject_Realloc()
ochPyObject_Free()
.För att allokera och frigöra Python-objekt använder du ”object”-familjen
PyObject_New
,PyObject_NewVar
ochPyObject_Del()
.
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
ochDL_IMPORT
är nu föråldrade. Initialiseringsfunktioner för Python-tilläggsmoduler bör nu deklareras med det nya makrotPyMODINIT_FUNC
, medan Python-kärnan i allmänhet kommer att använda makrotPyAPI_FUNC
ochPyAPI_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 angeMETH_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ändaPyArg_ParseTuple(args, "")
istället, men detta kommer att vara långsammare än att användaMETH_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, ochK
för unsigned long long.En ny funktion,
PyObject_DelItemString(mappning, char *nyckel)
lades till som kortform förPyObject_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
- ellerMETH_STATIC
-flaggorna i en metodsPyMethodDef
-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 utombsddb
.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 avSET_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 anropaPyCode_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. Ettjump
-kommando har lagts till ipdb
-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 ettOverflowError
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 enFutureWarning
. 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 skriva0xffffffffffL &~(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 funktionenget_distutil_options()
finns i dinsetup.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 enSyntaxWarning
-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.