
Dette er pyhacker, en phphacker-klon.
Her ligger forskellige python-relaterede ting, såsom tips & tricks, snippets, projekter og links. Enjoy.
Hvis man har arbejdet lidt med PHP, vil man formentlig kende til dens switch kontrolmetode. Til de uindviede kan det fortælles, at det er en måde at agere ud fra forskellige muligheder på en given værdi.
Python har ikke en decideret switch, ej heller under et andet navn. Dog er der et alternativ.
Pythons dictionaries kan nemlig bruges til at agere en switch:
val = 'hest'
def a(): print 'a'
def b(): print 'b'
def c(): print 'c'
{'hest':a,
'giraf':b,
'pingvin':c}[val]()
Denne snippet ville udskrive 'a', eftersom det er metoden a()'s output, og a() er associeret med "hest".
Du opnår ikke helt den samme fleksibilitet som i PHP (f.eks. er du nødt til at skrive en funktion for hver måde du vil agere på), men den kan være god nok i de fleste tilfælde. ¶
I forbindelse med Pythons import-mekanisme, som kun kan importere fra mapper længere nede i hierakiet, er det nogle gange nødvendigt at gå den anden vej. For at gøre dette kan man gøre brug af sys.path en oversigt over de mapper Python ser igennem, hvis ikke modulet kan importeres relativt i forhold til kodens nuværende scope. Hvis man vil tilføje mappen over den nuværende, variabelt i forhold til hvad denne er, kan man bruge følgende linje:
import os, sys
sys.path.append(os.path.abspath('.'))
os.path.abspath fungerer ved at tage det næstsidste element i en mappestreng (eksempelvis /home/user/python), uagtet om sidste element reelt er en mappe. (Altså vil førnævnte resultere i /home/user). ¶
Når Pythonkode bliver eksekveret cacher Python resultatet i en .pyc-fil, for at gøre det hurtigere at eksekvere koden en anden gang. Nogle gange, for eksempel hvis man arbejder på et projekt med flere personer, kan disse dog være irriterende når man samler koden. Hvis man sidder på et UNIX-baseret system såsom Linux eller Mac OS X kan disse fjernes med følgende korte kommando udført i terminalen:
find . -name '*.pyc' -delete
Denne kan selvfølgelig også bruges på andre typer af filer. ¶
Nogle gange er man interesseret i at gennemgå elementer, et element ad gangen. Dette gøres således med en list:
>>> l = ['a', 'b', 'c']
>>> for element in l:
... print element
...
a
b
c
Dog virker denne fremgangsmåde ikke helt på dictionaries:
>>> d = {'a': 'b', 'c': 'd'}
>>> for element in d:
... print element
...
a
c
Her kan man se at det altså kun er nøglerne der vises, mens man ofte også vil være interesseret i værdien. Dictionaries har dog en smart metode, items(), der forvandler den til en liste med tuple-par:
>>> d.items()
[('a', 'b'), ('c', 'd')]
Derved kan man altså tilgå nøgle/værdi–par i dictionaries således:
>>> for key, value in d.items():
... print key, value
...
a b
c d
Samme fremgangsmåde kan i øvrigt også bruges hvis man har flere end to elementer i hver tuple-gruppering:
>>> for a, b, c in (('a', 'b', 'c'), ('c', 'd', 'e')):
... print a, b, c
...
a b c
c d e
Fjerner tomme elementer i en list. Input fra Christian Jørgensen.
def trim(elm):
"""Perform a trim on a list."""
return [x for x in elm if len(x.strip()) > 0]
Python har en catch-all mulighed til at håndtere parametre — *args. Nogle gange vil man dog gerne være lidt fleksibel i hvordan man håndterer sine data, dvs. at lade parametrene enten komme som regulære parametre, eller som en list.
def listorarg(lst):
"""
A small function to check whether *args should be handled as that
list, or -- if args[0] is a list or a tuple -- assume that the
parameters are passed in that list/tuple
"""
if isinstance(lst[0], list) or isinstance(lst[0], tuple):
lst = lst[0]
return lst
Der er ikke noget magi her, men det kan være en praktisk rutine, hvis man vil give brugeren frihed, og ikke tvinge hende til at skulle gøre krumpsring for at bruge sin liste. En lignende metode bruges blandt andet i Pythons egne max() og min(). ¶
Python har en min()- og en max()-funktion, men der er ikke nogen decideret funktion til at undersøge hvorvidt værdier er ens. (Man kunne sammenligne min() og max()'s værdier, men det er lidt for grimt et hack efter min smag. Derudover kan det også give nogle performance-problemer, hvis man arbejder med meget store rækker af tal, fordi der skal foretages to kalkulationer på hver række, hvorimod denne metode kun arbejder indtil der er en afviger.)
def equal(*args):
"""
Check whether two or more variables are equal.
@require listorarg()
Can be called as any of the following:
o equal(2, 2, 2) # Regular function parameters passed
o equal([2, 2, 2]) # A list passed as parameter
"""
if len(args) == 0:
raise TypeError, 'equal expected at least 1 argument, got 0'
args = listorarg(args)
base = args[0]
for value in args:
if value != base:
return False
return True
equal() gør brug af listorarg() for at kunne modtage samme input som max() og min(), men returnerer naturligt nok ikke den samme type værdi. I modsætning til max() og min() kan den dog godt acceptere at modtage én værdi — i så tilfælde vil den returnere True. ¶
Python har en append-metode som ret simpelt tilføjer et element til listen. Ved brug af Pythons *args-struktur var jeg i stand til at skrive en funktion der kunne tage flere argumenter.
def enhancedappend(_list, *appends):
"""
list.append only takes 1 argument, this allows for more to be added
"""
for append in appends:
_list.append(append)
En simpel funktion til at tælle antallet af ord i en tekst, udregnet ud fra antallet af mellemrum, linjeskift og tabulær-indryk.
def wordcount(string):
"""
Count the number of words (determined by the number of spaces, tabs
and newlines)
"""
import re
string = string.strip()
string = re.sub(r'( |\n|\t)+', ' ', string)
return len(string.split(' '))