Python: característiques interessants
Escrit al 2007-07-27 22:39:42 per cpina
Python és un llenguatge de programació molt entenedor, però que a la vegada té característiques que el fan molt interessant.
A vegades un es pot quedar amb la part més superficial del llenguatge. De fet, amb aquesta part, ja es pot fer tot, però convé tenir a mà "més potència" ja sigui per fer tasques de forma més fàcil com per entendre codi d'altra gent.
Aquí es fa una petita enumeració de característiques/sintaxis que no són molt naturals de llegir, o que podem desconèixer que Python té això.
A vegades un es pot quedar amb la part més superficial del llenguatge. De fet, amb aquesta part, ja es pot fer tot, però convé tenir a mà "més potència" ja sigui per fer tasques de forma més fàcil com per entendre codi d'altra gent.
Aquí es fa una petita enumeració de característiques/sintaxis que no són molt naturals de llegir, o que podem desconèixer que Python té això.
map
Igual que Lisp: executa una funció sobre cada element de la llista.>>> import math
>>> l=[1,2,3,4,5,6]
>>> map(math.sqrt,l)
O un altre exemple:
>>> import string
>>> a=["hola "," bon dia "]
>>> map(string.strip,a)
['hola', 'bon dia']
(aplica una funció sobre cada element de la llista)
yield
Retorna el valor, però es pot seguir executant la funció amb .next()#!/usr/bin/python
def comptador():
i=0
for i in xrange(5):
print "Abans yield"
yield i*i
print "Despres yield"
a=comptador()
print a.next()
print a.next()
print a.next()
print a.next()
print a.next()
Manté l'estat de les variables. és el què fa servir, per exemple, xrange (range retorna una llista i punt, xrange retorna element a element i és molt més òptim per fer coses tipus for i in xrange(1,100)
<H2>Comprehension lists</H2>
(http://www.secnetix.de/~olli/Python/list_comprehensions.hawk)
Bàsicament: executa un bucle sobre una llista, permet posar una condició if i fer operacions sobre l'element que retorna de la llista. Retorna una nova llista.
Exemple 1:
>>> V = [2**i for i in xrange(13)]
>>> M = [x for x in xrange(10) if x % 2 == 0]
>>> print V
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
>>> print M
[0, 2, 4, 6, 8]
També pot ser una mica més embolicat:
>>> V = [(2**i,i) for i in xrange(13)]
>>> print V
[(1, 0), (2, 1), (4, 2), (8, 3), (16, 4), (32, 5), (64, 6), (128, 7), (256, 8), (512, 9), (1024, 10), (2048, 11), (4096, 12)]
Closures
Recomano llegir almenys el primer paràgraf, per entendre què són les closures:http://en.wikipedia.org/wiki/Closure_(computer_science)
També és força interessant la discusió:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/67618
Una petita explicació: les closures són quan una funció pot accedir a l'entorn (variables, objectes, etc.) de la funció que el crida. Mal utilitzat pot ser molt dolent: trenca les regles bàsiques d'encapsulació de la programació imperativa i de la programació orientada a objectes. Per això jo no recomanaria, en general, fer-les servir.
Les closures tenen un moment que són molt famoses (segurament perquè estan molt al dia a Ruby). Però les closures aporten poc respecte a tenir una classe. Podem llegir-ne opinions a aquest <A href="http://listas.aditel.org/archivos/python-es/2007-July/022870.html">email</A>, o bé <A href="http://listas.aditel.org/archivos/python-es/2007-July/022872.html">aquest.</A>
Tinc pendent de donar-hi algunes voltes més.
Decorators
(http://technofreakatchennai.wordpress.com/2007/03/08/decorators-in-python/)Inicialment permeten una cosa força simple: afegir, a algunes funcions, un codi previ i posterior a la crida de la funció. Però permet, evidentment, que el codi "previ" i "posterior" sigui fàcil de posar i treure. El codi és codi Python normal i pot modificar paràmetres, el codi en sí mateix, fer logs, etc. qualsevol cosa.
És com un wrapper, però permet posar varis decoradors apilats. També és possible fer-ho a classes: així enlloc de tenir N classes heredant d'altres classes per tenir totes les combinacions necessaries només cal afegir decoradors.
#!/usr/bin/python
def NomDecorador(fn): #Rep el nom de la funcio que se li passa
def _inner(x): #Es crida amb el primer parametre que se li havia passat
print "Has cridat amb parametre %d pero el crido amb %d" %(x,x+1)
fn(x+1)
print "Codi despres de la funcio"
return _inner
@NomDecorador
def myfunc(x):
print "I got", x
myfunc(5)
Convertir una tupla a arguments
L'operador * ens permet convertir una tupla a diferents paràmetres a la crida d'una funció, o rebre N paràmetres.#!/usr/bin/python
def rebre(primer,*altres):
print "Primer",primer
for i in altres:
print "Opc:",i
rebre(1,2,5,2)
rebre(1,*(6,8,5,2)) #com si fos rebre(1,6,8,5,2)
Veure com l'exemple és doble :-) (i per tant poc pedagògic): per un costat tenim l'operador "*" per rebre N elements (a la línia "def rebre") i per l'altre costat tenim com enviar la tupla com si fossin arguments normals, veure última línia.
Categories: Articles
Comentaris
- Sense comentaris