Vad är nytt i Python 2.4¶
- Författare:
A.M. Kuchling
I den här artikeln beskrivs de nya funktionerna i Python 2.4.1, som släpptes den 30 mars 2005.
Python 2.4 är en medelstor release. Den introducerar inte lika många förändringar som den radikala Python 2.2, men introducerar fler funktioner än den konservativa 2.3-versionen. De mest betydande nya språkfunktionerna är funktionsdekoratorer och generatoruttryck; de flesta andra ändringar är i standardbiblioteket.
Enligt CVS-ändringsloggarna tillämpades 481 korrigeringar och 502 buggar åtgärdades mellan Python 2.3 och 2.4. Båda siffrorna är sannolikt underskattningar.
Den här artikeln försöker inte ge en fullständig specifikation av varje enskild ny funktion, utan ger istället en kort introduktion till varje funktion. För fullständiga detaljer bör du hänvisa till dokumentationen för Python 2.4, till exempel Python Library Reference och Python Reference Manual. Ofta kommer du att hänvisas till PEP för en viss ny funktion för förklaringar av implementeringen och designrationaliteten.
PEP 218: Inbyggda set-objekt¶
Python 2.3 introducerade modulen sets
. C-implementeringar av set-datatyper har nu lagts till i Python-kärnan som två nya inbyggda typer, set(iterable)
och frozenset(iterable)
. De ger höghastighetsoperationer för medlemskapstestning, för att eliminera dubbletter från sekvenser och för matematiska operationer som unioner, korsningar, skillnader och symmetriska skillnader:
>>> a = set('abracadabra') # form a set from a string
>>> 'z' in a # fast membership testing
False
>>> a # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a) # convert back into a string
'arbcd'
>>> b = set('alacazam') # form a second set
>>> a - b # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters in both a and b
set(['a', 'c'])
>>> a ^ b # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])
>>> a.add('z') # add a new element
>>> a.update('wxy') # add multiple new elements
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x') # take one element out
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])
Typen frozenset()
är en oföränderlig version av set()
. Eftersom den är oföränderlig och hashbar kan den användas som en nyckel i en ordbok eller som en del av en annan uppsättning.
Modulen sets
finns kvar i standardbiblioteket och kan vara användbar om du vill underordna klasserna Set
eller ImmutableSet
. Det finns för närvarande inga planer på att avskriva modulen.
Se även
- PEP 218 - Lägga till en inbyggd objekttyp för set
Ursprungligen föreslagen av Greg Wilson och slutligen implementerad av Raymond Hettinger.
PEP 237: Förenande av långa heltal och heltal¶
Den långa övergångsprocessen för denna PEP, som påbörjades i Python 2.2, tar ytterligare ett steg framåt i Python 2.4. I 2.3 utlöste vissa heltalsoperationer som skulle bete sig annorlunda efter int/long-unifiering FutureWarning
-varningar och returnerade värden begränsade till 32 eller 64 bitar (beroende på din plattform). I 2.4 ger dessa uttryck inte längre någon varning utan ger istället ett annat resultat som vanligtvis är ett långt heltal.
De problematiska uttrycken är främst vänsterskift och långa hexadecimal- och oktalkonstanter. Till exempel resulterar 2 << 32
i en varning i 2.3, som utvärderas till 0 på 32-bitars plattformar. I Python 2.4 returnerar detta uttryck nu det korrekta svaret, 8589934592.
Se även
- PEP 237 - Unifiera långa heltal och heltal
Ursprunglig PEP skriven av Moshe Zadka och GvR. Ändringarna för 2.4 implementerades av Kalle Svensson.
PEP 289: Generatoruttryck¶
Iteratorfunktionen som introducerades i Python 2.2 och modulen itertools
gör det lättare att skriva program som loopar genom stora datamängder utan att ha hela datamängden i minnet på en gång. Listkomprehensioner passar inte in i den här bilden särskilt bra eftersom de producerar ett Python-listobjekt som innehåller alla objekt. Detta drar oundvikligen alla objekt till minnet, vilket kan vara ett problem om din datauppsättning är mycket stor. När man försöker skriva ett program i funktionell stil skulle det vara naturligt att skriva något i stil med:
links = [link for link in get_all_links() if not link.followed]
för länk i länkar:
...
istället för
för länk i get_all_links():
om länk.följd:
fortsätt
...
Den första formen är mer kortfattad och kanske mer läsbar, men om du har att göra med ett stort antal länkobjekt måste du skriva den andra formen för att undvika att ha alla länkobjekt i minnet samtidigt.
Generatoruttryck fungerar på samma sätt som listkomprehensioner men materialiserar inte hela listan; istället skapar de en generator som returnerar elementen ett efter ett. Exemplet ovan kan skrivas som:
länkar = (länk för länk i get_all_links() if not link.followed)
för länk i länkar:
...
Generatoruttryck måste alltid skrivas inom parentes, som i exemplet ovan. Parentesen som signalerar ett funktionsanrop räknas också, så om du vill skapa en iterator som omedelbart skickas till en funktion kan du skriva:
print sum(obj.count för obj i list_all_objects())
Generatoruttryck skiljer sig från listkomprehensioner på flera små sätt. Det mest anmärkningsvärda är att loopvariabeln (obj i exemplet ovan) inte är tillgänglig utanför generatoruttrycket. Listförståelser lämnar variabeln tilldelad till sitt senaste värde; framtida versioner av Python kommer att ändra detta, vilket gör att listförståelser matchar generatoruttryck i detta avseende.
Se även
- PEP 289 - Generatoruttryck
Föreslagen av Raymond Hettinger och implementerad av Jiwon Seo med tidiga insatser styrda av Hye-Shik Chang.
PEP 292: Enklare strängbyten¶
Några nya klasser i standardbiblioteket ger en alternativ mekanism för att ersätta variabler med strängar; denna typ av ersättning kan vara bättre för applikationer där otränade användare behöver redigera mallar.
Det vanliga sättet att ersätta variabler med namn är operatorn %
:
>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
'2: The Best of Times'
När man skriver mallsträngen kan det vara lätt att glömma i
eller s
efter den avslutande parentesen. Det här är inte ett stort problem om mallen finns i en Python-modul, eftersom du kör koden, får ett ”Unsupported format character” ValueError
och åtgärdar problemet. Men tänk på en applikation som Mailman där mallsträngar eller översättningar redigeras av användare som inte känner till Python-språket. Formatsträngens syntax är komplicerad att förklara för sådana användare, och om de gör ett misstag är det svårt att ge dem användbar feedback.
PEP 292 lägger till en Template
-klass till string
-modulen som använder $
för att ange en substitution:
>>> import string
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'The Best of Times'})
'2: The Best of Times'
Om en nyckel saknas i ordlistan kommer metoden substitute()
att ge upphov till ett KeyError
. Det finns också en safe_substitute()
-metod som ignorerar saknade nycklar:
>>> t = string.Template('$page: $title')
>>> t.safe_substitute({'page':3})
'3: $title'
Se även
- PEP 292 - Enklare ersättningar för strängar
Skriven och implementerad av Barry Warsaw.
PEP 318: Dekoratorer för funktioner och metoder¶
Python 2.2 utökade Pythons objektmodell genom att lägga till statiska metoder och klassmetoder, men det utökade inte Pythons syntax för att ge något nytt sätt att definiera statiska metoder eller klassmetoder. Istället var du tvungen att skriva en def
-sats på vanligt sätt och skicka den resulterande metoden till en staticmethod()
- eller classmethod()
-funktion som skulle packa upp funktionen som en metod av den nya typen. Din kod skulle se ut så här:
klass C:
def meth (cls):
...
meth = classmethod(meth) # Återkoppla namn till inplastad klassmetod
Om metoden var mycket lång skulle det vara lätt att missa eller glömma classmethod()
-inkallelsen efter funktionskroppen.
Avsikten var alltid att lägga till en syntax för att göra sådana definitioner mer läsbara, men vid tidpunkten för 2.2:s release var en bra syntax inte självklar. I dag är en bra syntax fortfarande inte självklar, men användarna efterfrågar enklare tillgång till funktionen; en ny syntaktisk funktion har lagts till för att tillgodose detta behov.
Den nya funktionen kallas ”funktionsdekoratorer”. Namnet kommer från idén att classmethod()
, staticmethod()
och vänner lagrar ytterligare information om ett funktionsobjekt; de dekorerar funktioner med mer detaljer.
Notationen är hämtad från Java och använder tecknet '@'
som indikator. Med hjälp av den nya syntaxen skulle exemplet ovan skrivas:
class C:
@classmethod
def meth (cls):
...
@classmethod
är en förkortning för uppgiften meth=classmethod(meth)
. Mer generellt, om du har följande:
@A
@B
@C
def f ():
...
Det motsvarar följande kod före inredningen:
def f(): ...
f = A(B(C(f)))
Dekoratorer måste komma på raden före en funktionsdefinition, en dekorator per rad, och kan inte vara på samma rad som def-satsen, vilket innebär att @A def f(): ...
är olagligt. Du kan bara dekorera funktionsdefinitioner, antingen på modulnivå eller inuti en klass; du kan inte dekorera klassdefinitioner.
En dekorator är bara en funktion som tar den funktion som ska dekoreras som argument och returnerar antingen samma funktion eller något nytt objekt. Returvärdet för dekoratorn behöver inte vara anropsbart (även om det vanligtvis är det), såvida inte ytterligare dekoratorer kommer att tillämpas på resultatet. Det är lätt att skriva egna dekoratorer. Följande enkla exempel sätter bara ett attribut på funktionsobjektet:
>>> def deco(func):
... func.attr = 'decorated'
... return func
...
>>> @deco
... def f(): pass
...
>>> f
<function f at 0x402ef0d4>
>>> f.attr
'decorated'
>>>
Som ett lite mer realistiskt exempel kontrollerar följande dekorator att det medföljande argumentet är ett heltal:
def require_int (func):
def wrapper (arg):
assert isinstance(arg, int)
return func(arg)
returnera omslag
@kräv_int
def p1 (arg):
skriv ut arg
@krav_int
def p2(arg):
skriv ut arg*2
Ett exempel i PEP 318 innehåller en finare version av denna idé som låter dig både ange den nödvändiga typen och kontrollera den returnerade typen.
Dekoratorfunktioner kan ta argument. Om argument anges anropas din dekoratorfunktion med endast dessa argument och måste returnera en ny dekoratorfunktion; denna funktion måste ta en enda funktion och returnera en funktion, enligt tidigare beskrivning. Med andra ord, @A @B @C(args)
blir:
def f(): ...
_deco = C(args)
f = A(B(_deco(f)))
Att få till det här kan vara en smula klurigt, men det är inte särskilt svårt.
En liten relaterad förändring gör attributet func_name
för funktioner skrivbart. Detta attribut används för att visa funktionsnamn i spårningar, så dekoratorer bör ändra namnet på alla nya funktioner som konstrueras och returneras.
Se även
- PEP 318 - Dekoratorer för funktioner, metoder och klasser
Skriven av Kevin D. Smith, Jim Jewett och Skip Montanaro. Flera personer skrev patchar som implementerade funktionsdekoratorer, men den som faktiskt checkades in var patch #979728, skriven av Mark Russell.
- https://wiki.python.org/moin/PythonDecoratorLibrary
Denna Wiki-sida innehåller flera exempel på dekoratorer.
PEP 322: Omvänd iteration¶
En ny inbyggd funktion, reversed(seq)
, tar en sekvens och returnerar en iterator som loopar över elementen i sekvensen i omvänd ordning.
>>> for i in reversed(xrange(1,4)):
... print i
...
3
2
1
Jämfört med utökad skivning, t.ex. range(1,4)[::-1]
, är reversed()
lättare att läsa, körs snabbare och använder betydligt mindre minne.
Observera att reversed()
endast accepterar sekvenser, inte godtyckliga iteratorer. Om du vill vända en iterator måste du först konvertera den till en lista med list()
.
>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
... print line
...
root:*:0:0:System Administrator:/var/root:/bin/tcsh
...
Se även
- PEP 322 - Omvänd iteration
Skriven och implementerad av Raymond Hettinger.
PEP 324: Ny delprocess Modul¶
Standardbiblioteket tillhandahåller ett antal sätt att exekvera en subprocess, med olika funktioner och olika komplexitetsnivåer. os.system(command)
är lätt att använda, men långsam (den kör en skalprocess som exekverar kommandot) och farlig (du måste vara försiktig med att escapa skalets metatecken). Modulen popen2
erbjuder klasser som kan fånga standardutdata och standardfel från subprocessen, men namngivningen är förvirrande. Modulen subprocess
rensar upp detta och ger ett enhetligt gränssnitt som erbjuder alla funktioner du kan behöva.
Istället för popen2
:s samling av klasser innehåller subprocess
en enda klass som heter subprocess.Popen
vars konstruktor stöder ett antal olika nyckelordsargument.
class Popen(args, bufsize=0, körbar=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
cwd=Ingen, env=Ingen, universal_newlines=False,
startupinfo=None, creationflags=0):
args är vanligen en sekvens av strängar som kommer att vara argumenten till det program som körs som subprocess. (Om argumentet shell är sant kan args vara en sträng som sedan skickas vidare till skalet för tolkning, precis som os.system()
gör)
stdin, stdout och stderr anger vad subprocessens in-, ut- och felströmmar ska vara. Du kan ange ett filobjekt eller en filbeskrivare, eller så kan du använda konstanten subprocess.PIPE
för att skapa en pipe mellan subprocessen och den överordnade processen.
Konstruktören har ett antal praktiska alternativ:
close_fds begär att alla filbeskrivare stängs innan subprocessen körs.
cwd anger den arbetskatalog i vilken subprocessen ska köras (standard är den överordnade processens arbetskatalog).
env är en ordbok som anger miljövariabler.
preexec_fn är en funktion som anropas innan barnet startas.
universal_newlines öppnar barnets in- och utdata med hjälp av Pythons universal newlines-funktion.
När du har skapat instansen Popen
kan du anropa dess metod wait()
för att pausa tills subprocessen har avslutats, poll()
för att kontrollera om den har avslutats utan paus, eller communicate(data)
för att skicka strängen data till subprocessens standardinmatning. communicate(data)
läser sedan alla data som underprocessen har skickat till sin standardutgång eller standardfel, och returnerar en tupel (stdout_data, stderr_data)
.
call()
är en genväg som skickar sina argument till Popen
-konstruktören, väntar på att kommandot ska slutföras och returnerar statuskoden för underprocessen. Den kan fungera som en säkrare motsvarighet till os.system()
:
sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
if sts == 0:
# Framgång
...
else:
# dpkg returnerade ett fel
...
Kommandot anropas utan användning av skalet. Om du verkligen vill använda skalet kan du lägga till shell=True
som ett nyckelordsargument och ange en sträng i stället för en sekvens:
sts = subprocess.call('dpkg -i /tmp/nytt-paket.deb', shell=True)
PEP:en tar olika exempel på shell- och Python-kod och visar hur de skulle kunna översättas till Python-kod som använder subprocess
. Att läsa detta avsnitt av PEP rekommenderas starkt.
Se även
- PEP 324 - subprocess - Ny processmodul
Skriven och implementerad av Peter Åstrand, med hjälp av bland andra Fredrik Lundh.
PEP 327: Decimal datatyp¶
Python har alltid haft stöd för flyttal (FP), baserat på den underliggande C double-typen, som datatyp. Men även om de flesta programmeringsspråk tillhandahåller en flyttalstyp, är många människor (även programmerare) omedvetna om att flyttal inte representerar vissa decimalfraktioner korrekt. Den nya typen Decimal
kan representera dessa fraktioner korrekt, upp till en användarspecificerad precisionsgräns.
Varför behövs Decimal?¶
Begränsningarna härrör från den representation som används för flyttal. FP-tal består av tre komponenter:
Tecknet, som är positivt eller negativt.
Mantissan, som är ett ensiffrigt binärt tal följt av en bråkdel. Till exempel är
1,01
i bas-2-notation1 + 0/2 + 1/4
, eller 1,25 i decimalnotation.Exponenten, som anger var decimaltecknet är placerat i det representerade talet.
Till exempel har talet 1,25 positivt tecken, ett mantissavärde på 1,01 (i binär) och en exponent på 0 (decimaltecknet behöver inte flyttas). Talet 5 har samma tecken och mantissa, men exponenten är 2 eftersom mantissan multipliceras med 4 (2 i potens med exponenten 2); 1,25 * 4 är lika med 5.
Moderna system har vanligtvis stöd för flyttal som följer en standard som kallas IEEE 754. C:s typ double implementeras vanligtvis som ett 64-bitars IEEE 754-tal, som använder 52 bitars utrymme för mantissan. Detta innebär att tal endast kan specificeras med 52 bitars precision. Om du försöker representera tal vars expansion upprepas i det oändliga, avbryts expansionen efter 52 bitar. Tyvärr måste de flesta programvaror producera utdata i bas 10, och vanliga bråk i bas 10 är ofta upprepade decimaler i binär. Till exempel är 1,1 decimal binär 1,0001100110011 ...
; .1 = 1/16 + 1/32 + 1/256 plus ett oändligt antal ytterligare termer. IEEE 754 måste hugga bort den oändligt upprepade decimalen efter 52 siffror, så representationen är något felaktig.
Ibland kan du se denna felaktighet när numret skrivs ut:
>>> 1.1
1.1000000000000001
Felaktigheten syns inte alltid när du skriver ut talet eftersom konverteringen av FP till decimalsträng tillhandahålls av C-biblioteket, och de flesta C-bibliotek försöker producera förnuftig utdata. Även om det inte visas, finns felaktigheten fortfarande kvar och efterföljande operationer kan förstora felet.
För många tillämpningar spelar detta ingen roll. Om jag plottar punkter och visar dem på min bildskärm är skillnaden mellan 1,1 och 1,1000000000000001 för liten för att synas. Rapporter begränsar ofta utdata till ett visst antal decimaler och om man avrundar till två, tre eller till och med åtta decimaler syns aldrig felet. För applikationer där det spelar roll är det dock mycket arbete att implementera egna aritmetiska rutiner.
Därför skapades typen Decimal
.
Typen Decimal
¶
En ny modul, decimal
, har lagts till i Pythons standardbibliotek. Den innehåller två klasser, Decimal
och Context
. Decimal
-instanser representerar tal, och Context
-instanser används för att sammanfatta olika inställningar som precision och standardavrundningsläge.
Decimal
-instanser är oföränderliga, precis som vanliga heltal och FP-tal i Python; när de väl har skapats kan du inte ändra det värde som en instans representerar. Decimal
-instanser kan skapas från heltal eller strängar:
>>> import decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")
Du kan också ange tuples som innehåller tecknet, mantissan representerad som en tuple av decimalsiffror och exponenten:
>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14.75")
Försiktighetsåtgärd: teckenbiten är ett booleskt värde, så 0 är positivt och 1 är negativt.
Konvertering från flyttal innebär lite av ett problem: ska FP-talet som representerar 1,1 bli decimaltalet för exakt 1,1, eller för 1,1 plus eventuella felaktigheter som införs? Beslutet blev att undvika problemet och lämna en sådan konvertering utanför API:et. Istället bör du konvertera flyttalstalet till en sträng med önskad precision och skicka strängen till Decimal
-konstruktören:
>>> f = 1.1
>>> decimal.Decimal(str(f))
Decimal("1.1")
>>> decimal.Decimal('%.12f' % f)
Decimal("1.100000000000")
När du har Decimal
-instanser kan du utföra de vanliga matematiska operationerna på dem. En begränsning: exponentiering kräver en heltalsexponent:
>>> a = decimal.Decimal('35.72')
>>> b = decimal.Decimal('1.73')
>>> a+b
Decimal("37.45")
>>> a-b
Decimal("33.99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.64739884393063583815028902")
>>> a ** 2
Decimal("1275.9184")
>>> a**b
Traceback (most recent call last):
...
decimal.InvalidOperation: x ** (non-integer)
Du kan kombinera Decimal
-instanser med heltal, men inte med flyttal:
>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (most recent call last):
...
TypeError: You can interact Decimal only with int, long or Decimal data types.
>>>
Decimal
-tal kan användas med modulerna math
och cmath
, men observera att de omedelbart konverteras till flyttal innan operationen utförs, vilket kan resultera i en möjlig förlust av precision och noggrannhet. Du kommer också att få tillbaka ett vanligt flyttal och inte ett Decimal
.
>>> import math, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j
Decimal
-instanser har en sqrt()
-metod som returnerar en Decimal
, men om du behöver andra saker, t.ex. trigonometriska funktioner, måste du implementera dem:
>>> d.sqrt()
Decimal("351364.1828820134592177245001")
Typen Context
¶
Instanser av klassen Context
kapslar in flera inställningar för decimaloperationer:
prec
är precisionen, antalet decimaler.rounding
anger avrundningssättet. Modulendecimal
har konstanter för de olika möjligheterna:ROUND_DOWN
,ROUND_CEILING
,ROUND_HALF_EVEN
och flera andra.traps
är en ordbok som anger vad som händer när vissa feltillstånd inträffar: antingen uppstår ett undantag eller så returneras ett värde. Några exempel på feltillstånd är division med noll, precisionsförlust och överflöd.
Det finns en trådlokal standardkontext tillgänglig genom att anropa getcontext()
; du kan ändra egenskaperna för denna kontext för att ändra standardprecision, avrundning eller trap-hantering. Följande exempel visar effekten av att ändra precisionen för standardkontexten:
>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.1428571428571428571428571429")
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.142857143")
Standardåtgärden för feltillstånd är valbar; modulen kan antingen returnera ett specialvärde som oändlighet eller inte ett tal, eller så kan undantag skapas:
>>> decimal.Decimal(1) / decimal.Decimal(0)
Traceback (most recent call last):
...
decimal.DivisionByZero: x / 0
>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
>>> decimal.Decimal(1) / decimal.Decimal(0)
Decimal("Infinity")
>>>
Instansen Context
har också olika metoder för att formatera tal, t.ex. to_eng_string()
och to_sci_string()
.
Mer information finns i dokumentationen för modulen decimal
, som innehåller en snabbstartshandledning och en referens.
Se även
- PEP 327 - Decimal datatyp
Skriven av Facundo Batista och implementerad av Facundo Batista, Eric Price, Raymond Hettinger, Aahz och Tim Peters.
- http://www.lahey.com/float.htm
I artikeln används Fortran-kod för att illustrera många av de problem som felaktigheter i flyttal kan orsaka.
- https://speleotrove.com/decimal/
En beskrivning av en decimalbaserad representation. Denna representation föreslås som en standard och ligger till grund för Pythons nya decimaltyp. Mycket av detta material har skrivits av Mike Cowlishaw, designer av Rexx-språket.
PEP 328: Import av flera linjer¶
En språkändring är en liten syntaktisk justering som syftar till att göra det enklare att importera många namn från en modul. I en from module import names
-sats är names en sekvens av namn åtskilda med kommatecken. Om sekvensen är mycket lång kan du antingen skriva flera importer från samma modul, eller så kan du använda backslashes för att undkomma radavslutningarna så här:
from SimpleXMLRPCServer import SimpleXMLRPCServer,\
SimpleXMLRPCRequestHandler,\
CGIXMLRPCRequestHandler,\
resolve_prickad_attribut
Den syntaktiska förändringen i Python 2.4 gör det helt enkelt möjligt att sätta namnen inom parentes. Python ignorerar nya rader inom ett uttryck med parenteser, så de bakre bindestrecken behövs inte längre:
from SimpleXMLRPCServer import (SimpleXMLRPCServer,
SimpleXMLRPCRequestHandler,
CGIXMLRPCRequestHandler,
resolve_dotted_attribute)
PEP föreslår också att alla import
-satser ska vara absoluta importer, med ett inledande .
-tecken för att indikera en relativ import. Denna del av PEP implementerades inte för Python 2.4, men slutfördes för Python 2.5.
Se även
- PEP 328 - Import: Flera rader och absolut/relativ
Skrivet av Aahz. Import av flera rader genomfördes av Dima Dorfman.
PEP 331: Lokaloberoende omvandling av flyttal/sträng¶
Modulen locale
låter Python-program välja olika konverteringar och visningskonventioner som är anpassade till ett visst land eller språk. Modulen var dock noga med att inte ändra den numeriska locale eftersom olika funktioner i Pythons implementation krävde att den numeriska locale skulle förbli inställd på 'C'
locale. Ofta berodde detta på att koden använde C-bibliotekets funktion atof()
.
Att inte ställa in den numeriska språkdräkten orsakade dock problem för tillägg som använde C-bibliotek från tredje part, eftersom de inte skulle ha rätt språkdräkt inställd. Det motiverande exemplet var GTK+, vars widgetar i användargränssnittet inte visade siffror i den aktuella språkdräkten.
Lösningen som beskrivs i PEP är att lägga till tre nya funktioner i Python API som endast utför ASCII-konverteringar och ignorerar locale-inställningen:
PyOS_ascii_strtod(str, ptr)
ochPyOS_ascii_atof(str, ptr)
konverterar båda en sträng till en C double.PyOS_ascii_formatd(buffer, buf_len, format, d)
konverterar ett double till en ASCII-sträng.
Koden för dessa funktioner kom från GLib-biblioteket (https://developer-old.gnome.org/glib/2.26/), vars utvecklare licensierade de relevanta funktionerna och donerade dem till Python Software Foundation. Modulen locale
kan nu ändra den numeriska språkdräkten, så att tillägg som GTK+ ger rätt resultat.
Se även
- PEP 331 - Lokaloberoende omvandling av float/sträng
Skriven av Christian R. Reis och implementerad av Gustavo Carneiro.
Andra språkliga förändringar¶
Här är alla ändringar som Python 2.4 gör i kärnan i Python-språket.
Dekoratorer för funktioner och metoder har lagts till (PEP 318).
Inbyggda
set()
ochfrozenset()
typer har lagts till (PEP 218). Andra nya inbyggda funktioner inkluderar funktionenreversed(seq)
(PEP 322).Generatoruttryck har lagts till (PEP 289).
Vissa numeriska uttryck returnerar inte längre värden som är begränsade till 32 eller 64 bitar (PEP 237).
Du kan nu sätta parenteser runt listan med namn i en
from module import names
-sats (PEP 328).Metoden
dict.update()
accepterar nu samma argumentformer som konstruktörendict
. Detta inkluderar alla mappningar, alla iterationer av nyckel/värde-par och nyckelordsargument. (Bidrag från Raymond Hettinger.)Strängmetoderna
ljust()
,rjust()
ochcenter()
tar nu ett valfritt argument för att ange ett annat fyllnadstecken än ett mellanslag. (Bidrag från Raymond Hettinger.)Strängar har också fått en
rsplit()
-metod som fungerar somsplit()
-metoden men delar från slutet av strängen. (Bidrag från Sean Reifschneider.)>>> 'www.python.org'.split('.', 1) ['www', 'python.org'] 'www.python.org'.rsplit('.', 1) ['www.python', 'org']
Tre nyckelordsparametrar, cmp, key och reverse, lades till i metoden
sort()
för listor. Dessa parametrar gör vissa vanliga användningar avsort()
enklare. Alla dessa parametrar är valfria.För parametern cmp ska värdet vara en jämförelsefunktion som tar två parametrar och returnerar -1, 0 eller +1 beroende på hur parametrarna jämförs. Denna funktion kommer sedan att användas för att sortera listan. Tidigare var detta den enda parametern som kunde anges till
sort()
.key bör vara en funktion med en parameter som tar ett element i en lista och returnerar en jämförelsenyckel för elementet. Listan sorteras sedan med hjälp av jämförelsenycklarna. I följande exempel sorteras en lista utan hänsyn till fall:
>>> L = ['A', 'b', 'c', 'D'] >>> L.sort() # Case-sensitive sort >>> L ['A', 'D', 'b', 'c'] >>> # Using 'key' parameter to sort list >>> L.sort(key=lambda x: x.lower()) >>> L ['A', 'b', 'c', 'D'] >>> # Old-fashioned way >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower())) >>> L ['A', 'b', 'c', 'D']
Det sista exemplet, där parametern cmp används, är det gamla sättet att utföra en sortering utan skiftlägeskänslighet. Det fungerar men är långsammare än att använda en key-parameter. Med key anropas
lower()
-metoden en gång för varje element i listan, medan den med cmp anropas två gånger för varje jämförelse, så med key sparas anrop avlower()
-metoden.För enkla nyckelfunktioner och jämförelsefunktioner är det ofta möjligt att undvika ett
lambda
-uttryck genom att använda en obunden metod i stället. Till exempel skrivs ovanstående sortering utan skiftlägeskänslighet bäst som:>>> L.sort(key=str.lower) >>> L ['A', 'b', 'c', 'D']
Slutligen tar parametern reverse ett booleskt värde. Om värdet är sant kommer listan att sorteras i omvänd ordning. Istället för
L.sort(); L.reverse()
kan du nu skrivaL.sort(reverse=True)
.Resultatet av sorteringen är nu garanterat stabilt. Det innebär att två poster med lika nycklar returneras i samma ordning som de matades in. Du kan t.ex. sortera en lista med personer efter namn och sedan sortera listan efter ålder, vilket resulterar i en lista som är sorterad efter ålder där personer med samma ålder är i namnsorterad ordning.
(Alla ändringar i
sort()
har gjorts av Raymond Hettinger.)Det finns en ny inbyggd funktion
sorted(iterable)
som fungerar som in-placelist.sort()
-metoden men som kan användas i uttryck. Skillnaderna är:indata kan vara vilken iterabel som helst;
en nybildad kopia sorteras, varvid originalet lämnas intakt; och
uttrycket returnerar den nya sorterade kopian
>>> L = [9,7,8,3,2,4,1,6,5] >>> [10+i for i in sorted(L)] # usable in a list comprehension [11, 12, 13, 14, 15, 16, 17, 18, 19] >>> L # original is left unchanged [9,7,8,3,2,4,1,6,5] >>> sorted('Monty Python') # any iterable may be an input [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y'] >>> # List the contents of a dict sorted by key values >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5) >>> for k, v in sorted(colormap.iteritems()): ... print k, v ... black 4 blue 2 green 3 red 1 yellow 5
(Bidrag från Raymond Hettinger.)
Integer-operationer kommer inte längre att utlösa en
OverflowWarning
. VarningenOverflowWarning
kommer att försvinna i Python 2.5.Tolken har fått en ny switch,
-m
, som tar ett namn, söker efter motsvarande modul påsys.path
och kör modulen som ett skript. Till exempel kan du nu köra Python-profileraren medpython -m profile
. (Bidrag från Nick Coghlan.)Funktionerna
eval(expr, globals, locals)
ochexecfile(filnamn, globals, locals)
samtexec
-satsen accepterar nu valfri mappningstyp för parametern locals. Tidigare var detta tvunget att vara en vanlig Python-ordbok. (Bidrag från Raymond Hettinger.)Den inbyggda funktionen
zip()
ochitertools.izip()
returnerar nu en tom lista om de anropas utan argument. Tidigare gav de upphov till ettTypeError
-undantag. Detta gör dem mer lämpade för användning med argumentlistor av varierande längd:>>> def transpose(array): ... return zip(*array) ... >>> transpose([(1,2,3), (4,5,6)]) [(1, 4), (2, 5), (3, 6)] >>> transpose([]) []
(Bidrag från Raymond Hettinger.)
Om ett fel uppstår vid import av en modul lämnas inte längre ett delvis initialiserat modulobjekt kvar i
sys.modules
. Det ofullständiga modulobjektet som lämnades kvar kunde hindra ytterligare import av samma modul från att lyckas, vilket ledde till förvirrande fel. (Åtgärdat av Tim Peters.)None
är nu en konstant; kod som binder ett nytt värde till namnetNone
är nu ett syntaxfel. (Bidrag från Raymond Hettinger.)
Optimeringar¶
De inre looparna för list- och tuple-slicing har optimerats och körs nu ungefär en tredjedel snabbare. De inre looparna för ordböcker optimerades också, vilket resulterade i prestandaökningar för
keys()
,values()
,items()
,iterkeys()
,itervalues()
ochiteritems()
. (Bidrag från Raymond Hettinger.)Maskineriet för att växa och krympa listor har optimerats för hastighet och utrymmeseffektivitet. Att lägga till och plocka från listor går nu snabbare tack vare effektivare kodvägar och mindre frekvent användning av det underliggande systemet
realloc()
. Listförståelse gynnas också.list.extend()
har också optimerats och konverterar inte längre sitt argument till en tillfällig lista innan baslistan utökas. (Bidrag från Raymond Hettinger.)list()
,tuple()
,map()
,filter()
ochzip()
körs nu flera gånger snabbare med argument som inte är sekvenser och som innehåller metoden__len__()
. (Bidrag från Raymond Hettinger.)Metoderna
list.__getitem__()
,dict.__getitem__()
ochdict.__contains__()
är nu implementerade sommethod_descriptor
-objekt i stället förwrapper_descriptor
-objekt. Denna form av åtkomst fördubblar deras prestanda och gör dem mer lämpliga att använda som argument till funktionaler:map(mydict.__getitem__, keylist)
. (Bidrag från Raymond Hettinger.)Lade till en ny opcode,
LIST_APPEND
, som förenklar den genererade bytekoden för listförståelser och snabbar upp dem med ungefär en tredjedel. (Bidrag från Raymond Hettinger.)Bytekodsoptimeraren Peephole har förbättrats för att producera kortare och snabbare bytekod; anmärkningsvärt nog är den resulterande bytekoden mer läsbar. (Förbättrad av Raymond Hettinger.)
Strängkonkateneringar i satser av formen
s = s + "abc"
ochs += "abc"
utförs nu mer effektivt under vissa omständigheter. Denna optimering kommer inte att finnas i andra Python-implementationer som Jython, så du bör inte förlita dig på den; att användajoin()
-metoden för strängar rekommenderas fortfarande när du effektivt vill limma ihop ett stort antal strängar. (Bidrag från Armin Rigo.)
Nettoresultatet av 2.4-optimeringarna är att Python 2.4 kör pystone-riktmärket cirka 5% faster än Python 2.3 och 35% faster än Python 2.2. (pystone är inte ett särskilt bra riktmärke, men det är den mest använda mätningen av Pythons prestanda. Dina egna applikationer kan visa större eller mindre fördelar med Python 2.4.)
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
asyncore
:s funktionloop()
har nu en parameter count som låter dig utföra ett begränsat antal genomgångar av pollingloopen. Standardinställningen är fortfarande att loopa för evigt.Modulen
base64
har nu mer komplett RFC 3548-stöd för Base64-, Base32- och Base16-kodning och -avkodning, inklusive valfri skiftlägesändring och valfria alternativa alfabet. (Bidrag från Barry Warsaw.)Modulen
bisect
har nu en underliggande C-implementering för förbättrad prestanda. (Bidrag från Dmitry Vasiliev.)CJKCodecs samlingar av östasiatiska codecs, som underhålls av Hye-Shik Chang, integrerades i 2.4. De nya kodningarna är:
Kinesiska (PRC): gb2312, gbk, gb18030, big5hkscs, hz
Kinesiska (ROC): big5, cp950
- Japanska: cp932, euc-jis-2004, euc-jp, euc-jisx0213, iso-2022-jp,
iso-2022-jp-1, iso-2022-jp-2, iso-2022-jp-3, iso-2022-jp-ext, iso-2022-jp-2004, shift-jis, shift-jisx0213, shift-jis-2004
Koreanska: cp949, euc-kr, johab, iso-2022-kr
Några andra nya kodningar har lagts till: HP Roman8, ISO_8859-11, ISO_8859-16, PCTP-154 och TIS-620.
UTF-8- och UTF-16-codecs klarar nu bättre av att ta emot partiell indata. Tidigare försökte klassen
StreamReader
att läsa mer data, vilket gjorde det omöjligt att återuppta avkodningen från strömmen. Metodenread()
kommer nu att returnera så mycket data som möjligt och framtida anrop kommer att återuppta avkodningen där tidigare anrop slutade. (Implementerad av Walter Dörwald.)Det finns en ny
collections
-modul för olika specialiserade datatyper för samlingar. För närvarande innehåller den bara en typ,deque
, en kö med dubbla ändar som stöder effektivt tillägg och borttagning av element från båda ändarna:>>> from collections import deque >>> d = deque('ghi') # make a new deque with three items >>> d.append('j') # add a new entry to the right side >>> d.appendleft('f') # add a new entry to the left side >>> d # show the representation of the deque deque(['f', 'g', 'h', 'i', 'j']) >>> d.pop() # return and remove the rightmost item 'j' >>> d.popleft() # return and remove the leftmost item 'f' >>> list(d) # list the contents of the deque ['g', 'h', 'i'] >>> 'h' in d # search the deque True
Flera moduler, t.ex. modulerna
Queue
ochthreading
, utnyttjar nucollections.deque
för förbättrad prestanda. (Bidrag från Raymond Hettinger.)Klasserna
ConfigParser
har förbättrats något. Metodenread()
returnerar nu en lista över de filer som har analyserats framgångsrikt, och metodenset()
ger upphov tillTypeError
om ett value-argument som inte är en sträng skickas. (Bidrag från John Belmonte och David Goodger.)Modulen
curses
har nu stöd för ncurses-tilläggetuse_default_colors()
. På plattformar där terminalen stöder transparens gör detta det möjligt att använda en transparent bakgrund. (Bidrag från Jörg Lehmann.)Modulen
difflib
innehåller nu en klassHtmlDiff
som skapar en HTML-tabell som visar en jämförelse sida vid sida mellan två versioner av en text. (Bidrag från Dan Gass.)Paketet
email
har uppdaterats till version 3.0, som innehåller flera föråldrade API:er och tar bort stöd för Python-versioner tidigare än 2.3. I version 3.0 av paketet används en ny inkrementell parser för MIME-meddelanden, som finns i modulenemail.FeedParser
. Den nya parsern kräver inte att hela meddelandet läses in i minnet och ger inte upphov till undantag om ett meddelande är felaktigt utformat; i stället registreras eventuella problem i meddelandets attributdefect
. (Utvecklad av Anthony Baxter, Barry Warsaw, Thomas Wouters och andra)Modulen
heapq
har konverterats till C. Den tiofaldigt förbättrade hastigheten gör att modulen lämpar sig för hantering av stora datamängder. Dessutom har modulen två nya funktionernlargest()
ochnsmallest()
som använder heaps för att hitta de N största eller minsta värdena i en datauppsättning utan att behöva göra en fullständig sortering. (Bidrag från Raymond Hettinger.)Modulen
httplib
innehåller nu konstanter för HTTP-statuskoder som definieras i olika HTTP-relaterade RFC-dokument. Konstanterna har namn somOK
,CREATED
,CONTINUE
ochMOVED_PERMANENTLY
; använd pydoc för att få en fullständig lista. (Bidrag från Andrew Eland.)Modulen
imaplib
har nu stöd för IMAP:s THREAD-kommando (bidrag från Yves Dionne) och de nya metodernadeleteacl()
ochmyrights()
(bidrag från Arnaud Mazin).Modulen
itertools
har utökats med funktionengroupby(iterable[, *func*])
. iterable är något som kan itereras över för att returnera en ström av element, och den valfria parametern func är en funktion som tar ett element och returnerar ett nyckelvärde; om den utelämnas är nyckeln helt enkelt själva elementet.groupby()
grupperar sedan elementen i undersekvenser som har matchande värden på nyckeln, och returnerar en serie av 2-tupler som innehåller nyckelvärdet och en iterator över undersekvensen.Här är ett exempel för att göra det tydligare. Funktionen key returnerar helt enkelt om ett tal är jämnt eller udda, så resultatet av
groupby()
är att returnera på varandra följande serier av udda eller jämna tal.>>> import itertools >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14] >>> for key_val, it in itertools.groupby(L, lambda x: x % 2): ... print key_val, list(it) ... 0 [2, 4, 6] 1 [7] 0 [8] 1 [9, 11] 0 [12, 14] >>>
groupby()
används vanligen med sorterad indata. Logiken förgroupby()
liknar Unixuniq
-filter, vilket gör det praktiskt för att eliminera, räkna eller identifiera duplicerade element:>>> word = 'abracadabra' >>> letters = sorted(word) # Turn string into a sorted list of letters >>> letters ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r'] >>> for k, g in itertools.groupby(letters): ... print k, list(g) ... a ['a', 'a', 'a', 'a', 'a'] b ['b', 'b'] c ['c'] d ['d'] r ['r', 'r'] >>> # List unique letters >>> [k for k, g in groupby(letters)] ['a', 'b', 'c', 'd', 'r'] >>> # Count letter occurrences >>> [(k, len(list(g))) for k, g in groupby(letters)] [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
(Bidrag från Hye-Shik Chang.)
itertools
har också fått en funktion som hetertee(iterator, N)
som returnerar N oberoende iteratorer som replikerar iterator. Om N utelämnas är standardvärdet 2.>>> L = [1,2,3] >>> i1, i2 = itertools.tee(L) >>> i1,i2 (<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>) >>> list(i1) # Run the first iterator to exhaustion [1, 2, 3] >>> list(i2) # Run the second iterator to exhaustion [1, 2, 3]
Observera att
tee()
måste behålla kopior av de värden som iteratorn returnerar; i värsta fall kan den behöva behålla dem alla. Detta bör därför användas försiktigt om den ledande iteratorn kan springa långt före den efterföljande iteratorn i en lång ström av inmatningar. Om separationen är stor kan du lika gärna användalist()
istället. När iteratorerna ligger nära varandra ärtee()
perfekt. Möjliga tillämpningar inkluderar bokmärken, fönster eller lookahead-iteratorer. (Bidrag från Raymond Hettinger.)Ett antal funktioner har lagts till i modulen
locale
, t.ex.bind_textdomain_codeset()
för att ange en viss kodning och en familj avl*gettext()
-funktioner som returnerar meddelanden i den valda kodningen. (Bidrag från Gustavo Niemeyer.)Några nyckelordsargument har lagts till i
logging
-paketetsbasicConfig()
-funktion för att förenkla loggkonfigurationen. Standardbeteendet är att logga meddelanden till standardfel, men olika nyckelordsargument kan anges för att logga till en viss fil, ändra loggningsformatet eller ställa in loggningsnivån. Till exempel:import logging logging.basicConfig(filename='/var/log/application.log', level=0, # Log all messages format='%(levelname):%(process):%(thread):%(message)')
Andra tillägg till
logging
-paketet inkluderar enlog(level, msg)
bekvämlighetsmetod, samt enTimedRotatingFileHandler
-klass som roterar sina loggfiler med ett tidsbestämt intervall. Modulen hade redanRotatingFileHandler
, som roterade loggarna när filen översteg en viss storlek. Båda klasserna härstammar från en ny klassBaseRotatingHandler
som kan användas för att implementera andra rotationshanterare.(Ändringar implementerade av Vinay Sajip.)
Modulen
marshal
delar nu internerade strängar vid uppackning av en datastruktur. Detta kan krympa storleken på vissa pickle-strängar, men den primära effekten är att göra.pyc
-filer betydligt mindre. (Bidrag från Martin von Löwis.)nntplib
-modulensNNTP
-klass fick metodernadescription()
ochdescriptions()
för att hämta beskrivningar av nyhetsgrupper för en enda grupp eller för ett antal grupper. (Bidrag från Jürgen A. Erhard.)Två nya funktioner har lagts till i modulen
operator
,attrgetter(attr)
ochitemgetter(index)
. Båda funktionerna returnerar anropbara filer som tar ett enda argument och returnerar motsvarande attribut eller objekt; dessa anropbara filer är utmärkta datautdragare när de används medmap()
ellersorted()
. Till exempel:>>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)] >>> map(operator.itemgetter(0), L) ['c', 'd', 'a', 'b'] >>> map(operator.itemgetter(1), L) [2, 1, 4, 3] >>> sorted(L, key=operator.itemgetter(1)) # Sort list by second tuple item [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
(Bidrag från Raymond Hettinger.)
Modulen
optparse
har uppdaterats på olika sätt. Modulen skickar nu sina meddelanden genomgettext.gettext()
, vilket gör det möjligt att internationalisera Optiks hjälp- och felmeddelanden. Hjälpmeddelanden för alternativ kan nu inkludera strängen'%default'
, som kommer att ersättas av alternativets standardvärde. (Bidrag från Greg Ward.)Den långsiktiga planen är att avskaffa
rfc822
-modulen i någon framtida Python-utgåva till förmån föremail
-paketet. För detta ändamål har funktionenemail.Utils.formatdate
ändrats för att göra den användbar som en ersättning förrfc822.formatdate()
. Du kanske vill skriva ny kod för e-postbehandling med detta i åtanke. (Ändringen implementerades av Anthony Baxter.)En ny funktion
urandom(n)
har lagts till i modulenos
, som returnerar en sträng innehållande n bytes slumpmässiga data. Denna funktion ger tillgång till plattformsspecifika källor till slumpmässiga data såsom/dev/urandom
på Linux eller Windows CryptoAPI. (Bidrag från Trevor Perrin.)Ytterligare en ny funktion:
os.path.lexists(path)
returnerar sant om filen som anges av path existerar, oavsett om det är en symbolisk länk eller inte. Detta skiljer sig från den befintliga funktionenos.path.exists(path)
, som returnerar false om path är en symbolisk länk som pekar på en destination som inte existerar. (Bidrag från Beni Cherniavsky.)En ny funktion
getsid()
lades till i modulenposix
som ligger till grund för modulenos
. (Bidrag från J. Raynor.)Modulen
poplib
har nu stöd för POP över SSL. (Bidrag från Hector Urtubia.)Modulen
profile
kan nu profilera C-tilläggsfunktioner. (Bidrag från Nick Bastin.)Modulen
random
har en ny metod som hetergetrandbits(N)
som returnerar ett långt heltal N bitar långt. Den befintliga metodenrandrange()
använder nugetrandbits()
där det är lämpligt, vilket gör generering av godtyckligt stora slumptal mer effektiv. (Bidrag från Raymond Hettinger.)Det språk för reguljära uttryck som accepteras av modulen
re
har utökats med enkla villkorliga uttryck, skrivna som(?(group)A|B)
. group är antingen ett numeriskt grupp-ID eller ett gruppnamn definierat med(?P<group>...)
tidigare i uttrycket. Om den angivna gruppen matchade, kommer det reguljära uttrycksmönstret A att testas mot strängen; om gruppen inte matchade, kommer mönstret B att användas istället. (Bidrag från Gustavo Niemeyer.)Modulen
re
är inte heller längre rekursiv, tack vare ett enormt arbete av Gustavo Niemeyer. I en rekursiv reguljär uttrycksmotor resulterar vissa mönster i att en stor mängd C-stackutrymme förbrukas, och det var möjligt att överfylla stacken. Om du till exempel matchade en 30000-byte-sträng meda
-tecken mot uttrycket(a|b)+
, förbrukades en stackram per tecken. Python 2.3 försökte kontrollera för stacköverflöd och skapa ettRuntimeError
-undantag, men vissa mönster kunde kringgå kontrollen och om du hade otur kunde Python få segfault. Python 2.4:s motor för reguljära uttryck kan matcha det här mönstret utan problem.Modulen
signal
utför nu en striktare felkontroll på parametrarna till funktionensignal.signal()
. Till exempel kan du inte ställa in en hanterare påSIGKILL
-signalen; tidigare versioner av Python skulle tyst acceptera detta, men 2.4 kommer att ge upphov till ettRuntimeError
-undantag.Två nya funktioner har lagts till i modulen
socket
.socketpair()
returnerar ett par anslutna socklar ochgetservbyport(port)
söker upp servicenamnet för ett givet portnummer. (Bidrag från Dave Cole och Barry Warsaw.)Funktionen
sys.exitfunc()
har utgått. Kod bör använda den befintliga modulenatexit
, som korrekt hanterar anrop av flera exit-funktioner. Så småningom kommersys.exitfunc()
att bli ett rent internt gränssnitt, som endast nås avatexit
.Modulen
tarfile
genererar nu tar-filer i GNU-format som standard. (Bidrag från Lars Gustäbel.)Modulen
threading
har nu ett elegant och enkelt sätt att stödja trådlokala data. Modulen innehåller enlocal
-klass vars attributvärden är lokala för olika trådar.import threading data = threading.local() data.number = 42 data.url = ('www.python.org', 80)
Andra trådar kan tilldela och hämta sina egna värden för attributen
number
ochurl
. Du kan underklassalocal
för att initiera attribut eller lägga till metoder. (Bidrag från Jim Fulton.)Modulen
timeit
inaktiverar nu automatiskt periodisk skräpinsamling under tidtagningsslingan. Denna förändring gör på varandra följande tidtagningar mer jämförbara. (Bidrag från Raymond Hettinger.)Modulen
weakref
stöder nu ett större antal objekt, inklusive Python-funktioner, klassinstanser, set, frozensets, deques, arrays, filer, sockets och objekt med mönster för reguljära uttryck. (Bidrag från Raymond Hettinger.)Modulen
xmlrpclib
stöder nu ett tillägg för flera anrop för att överföra flera XML-RPC-anrop i en enda HTTP-operation. (Bidrag från Brian Quinlan.)Modulerna
mpz
,rotor
ochxreadlines
har tagits bort.
doctest¶
Modulen doctest
har genomgått en betydande omarbetning tack vare Edward Loper och Tim Peters. Testning kan fortfarande vara lika enkelt som att köra doctest.testmod()
, men omarbetningarna gör det möjligt att anpassa modulens funktion på olika sätt
Den nya DocTestFinder
-klassen extraherar testerna från ett visst objekts docstrings:
def f (x, y):
""">>> f(2,2)
4
>>> f(3,2)
6
"""
return x*y
finder = doctest.DocTestFinder()
# Get list of DocTest instances
tests = finder.find(f)
Den nya DocTestRunner
-klassen kör sedan enskilda tester och kan producera en sammanfattning av resultaten:
runner = doctest.DocTestRunner()
för t i tester:
tried, failed = runner.run(t)
runner.summarize(verbose=1)
Exemplet ovan ger följande resultat:
1 objekt klarade alla tester:
2 tester i f
2 tester i 1 objekt.
2 godkända och 0 underkända.
Testet godkändes.
DocTestRunner
använder en instans av klassen OutputChecker
för att jämföra den förväntade utdata med den faktiska utdata. Denna klass tar ett antal olika flaggor som anpassar dess beteende; ambitiösa användare kan också skriva en helt ny underklass av OutputChecker
.
Standardutdatakontrollen har ett antal praktiska funktioner. Till exempel, med doctest.ELLIPSIS
option flagga, en ellips (...
) i den förväntade utdata matchar alla delsträngar, vilket gör det lättare att tillgodose utdata som varierar på mindre sätt:
def o (n):
""">>> o(1)
<__main__.C instance at 0x...>
>>>
"""
En annan speciell sträng, <BLANKLINE>
, matchar en tom rad:
def p (n):
""">>> p(1)
<BLANKLINE>
>>>
"""
En annan ny funktion är att producera en diff-stilsvisning av utdata genom att ange alternativflaggorna doctest.REPORT_UDIFF
(unified diffs), doctest.REPORT_CDIFF
(context diffs) eller doctest.REPORT_NDIFF
(delta-style). Till exempel:
def g (n):
""">>> g(4)
here
is
a
lengthy
>>>"""
L = 'here is a rather lengthy list of words'.split()
for word in L[:n]:
print word
Om du kör testerna för ovanstående funktion med doctest.REPORT_UDIFF
specificerad får du följande resultat:
**********************************************************************
Fil "t.py", rad 15, i g
Misslyckat exempel:
g(4)
Skillnader (enhetlig diff med -förväntat +verkligt):
@@ -2,3 +2,3 @@
är
a
-lång
+mer
**********************************************************************
Ändringar i Build och C API¶
Några av ändringarna i Pythons byggprocess och i C API:et är följande:
Tre nya bekvämlighetsmakron har lagts till för vanliga returvärden från tilläggsfunktioner:
Py_RETURN_NONE
,Py_RETURN_TRUE
ochPy_RETURN_FALSE
. (Bidrag från Brett Cannon.)Ett annat nytt makro,
Py_CLEAR
, minskar referensantalet för obj och sätter obj till nollpekaren. (Bidrag från Jim Fulton.)En ny funktion,
PyTuple_Pack(N, obj1, obj2, ..., objN)
, konstruerar tuplar från en argumentlista med variabel längd av Python-objekt. (Bidrag från Raymond Hettinger.)En ny funktion,
PyDict_Contains(d, k)
, implementerar snabba ordboksuppslagningar utan att maskera undantag som uppstår under uppslagningsprocessen. (Bidrag från Raymond Hettinger.)Makrot Py_IS_NAN(X) returnerar 1 om dess float- eller double-argument X är ett NaN. (Bidrag från Tim Peters.)
C-kod kan undvika onödig låsning genom att använda den nya
PyEval_ThreadsInitialized()
-funktionen för att avgöra om några trådoperationer har utförts. Om denna funktion returnerar false behövs inga låsoperationer. (Bidrag från Nick Coghlan.)En ny funktion,
PyArg_VaParseTupleAndKeywords()
, är samma sak somPyArg_ParseTupleAndKeywords()
men tar enva_list
istället för ett antal argument. (Bidrag från Greg Chapman.)En ny metodflagga,
METH_COEXIST
, gör att en funktion som definieras i slots kan samexistera med enPyCFunction
med samma namn. Detta kan halvera åtkomsttiden för en metod somset.__contains__()
. (Bidrag från Raymond Hettinger.)Python kan nu byggas med ytterligare profilering för själva tolken, avsedd som ett hjälpmedel för personer som utvecklar Python-kärnan. Om du lägger till
--enable-profiling
i skriptet configure kan du profilera tolken med gprof, och om du lägger till--with-tsc
kan du profilera med hjälp av Pentiums Time-Stamp-Counter-register. Observera att bytet--with-tsc
är något felaktigt namngivet, eftersom profileringsfunktionen även fungerar på PowerPC-plattformen, även om den processorarkitekturen inte kallar registret för ”TSC-registret”. (Bidrag från Jeremy Hylton.)Typen
tracebackobject
har bytt namn tillPyTracebackObject
.
Hamnspecifika ändringar¶
Windows-porten bygger nu under MSVC++ 7.1 såväl som version 6. (Bidrag från Martin von Löwis.)
Portning till Python 2.4¶
I detta avsnitt listas tidigare beskrivna ändringar som kan kräva ändringar i din kod:
Vänsterförskjutningar och hexadecimala/oktala konstanter som är för stora utlöser inte längre en
FutureWarning
och returnerar ett värde begränsat till 32 eller 64 bitar; istället returnerar de ett långt heltal.Integer-operationer kommer inte längre att utlösa en
OverflowWarning
. VarningenOverflowWarning
kommer att försvinna i Python 2.5.De inbyggda funktionerna
zip()
ochitertools.izip()
returnerar nu en tom lista istället för att ge upphov till ettTypeError
-undantag om de anropas utan argument.Du kan inte längre jämföra instanserna
date
ochdatetime
som tillhandahålls av modulendatetime
. Två instanser av olika klasser kommer nu alltid att vara ojämlika och relativa jämförelser (<
,>
) kommer att ge upphov till ettTypeError
.dircache.listdir()
skickar nu undantag till anroparen istället för att returnera tomma listor.LexicalHandler.startDTD()
brukade ta emot offentliga ID:n och system-ID:n i fel ordning. Detta har korrigerats; applikationer som förlitar sig på den felaktiga ordningen måste åtgärdas.fcntl.ioctl()
varnar nu om argumentet mutate utelämnas och är relevant.Modulen
tarfile
genererar nu tar-filer i GNU-format som standard.Om ett fel inträffar vid import av en modul lämnas inte längre ett delvis initialiserat modulobjekt kvar i
sys.modules
.None
är nu en konstant; kod som binder ett nytt värde till namnetNone
är nu ett syntaxfel.Funktionen
signals.signal()
ger nu upphov till ettRuntimeError
-undantag för vissa olagliga värden; tidigare passerade dessa fel tyst. Du kan t.ex. inte längre ställa in en hanterare för signalenSIGKILL
.
Tack till¶
Författaren vill tacka följande personer för förslag, korrigeringar och hjälp med olika utkast av denna artikel: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger, Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider, Sadruddin Rejeb.