====== Python basic recipes ====== ===== Base lib ===== ==== dicts ==== === pop === >>> a = {'a': 1, 'b': 2} >>> a.pop('a') 1 >>> a {'b': 2} >>> a.pop('a') Traceback (most recent call last): File "", line 1, in KeyError: 'a' >>> a.pop('a', 0) 0 ==== Custom parameters in logging ==== import logging extra = {'app_name':'Super App'} logger = logging.getLogger(__name__) syslog = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') syslog.setFormatter(formatter) logger.setLevel(logging.INFO) logger.addHandler(syslog) logger = logging.LoggerAdapter(logger, extra) logger.info('The sky is so blue') logs (something like): ''2013-07-09 17:39:33,596 Super App : The sky is so blue'' ===== Strings ===== ==== Template ==== from string import Template s = Template('$who is from $where') d = {} d['who'] = 'Bill' d['where'] = 'Boston' p = s.substitute(d) ==== Decorators ==== === Class decorator === def decorator(cls): class Wrapper(object): def __init__(self,*args,**kwargs): self.wrapper = cls(*args,**kwargs) """ def __getattr__(self, name, *args, **kwargs): print('Getting the {} of {}, {}, {}'.format(name, self.wrapped, repr(args), repr(kwargs))) return getattr(self.wrapped, name) """ def __getattr__(self, attr): print attr def wrapper(*args, **kw): print('called with %r and %r' % (args, kw)) return getattr(self.wrapper, attr)(*args, **kw) return wrapper return Wrapper @decorator class C(object): def method(self, x, y): print 'b' if __name__ == '__main__': c = C() c.method(1,2) ===== Call several Python functions ===== #!/usr/bin/python # -*- coding: utf-8 *-* def funciona (a, b): return a + b calls = [(funciona, {'a': 1, 'b': 3})] for c in calls: print c[0](**c[1]) ===== Paths ===== Path from where the script was called: cwd = os.getcwd() Script relative path: __file__ Get the relative path of a file (the folder where it is): os.path.dirname(__file__) ''os.path.abspath'': Get the absolute path: os.path.abspath(the_relative_path) ''os.path.dirname'': The parent path of the folder\file: print(root) print(os.path.dirname(root)) /home/alfred/Desktop/presentesNOW/ReDesktop-SUBJECTS/Kibbutz /home/alfred/Desktop/presentesNOW/ReDesktop-SUBJECTS ''os.path.basename'': The file\folder name: print(root) print(os.path.basename(root)) /home/alfred/Desktop/presentesNOW/ReDesktop-SUBJECTS/Kibbutz Kibbutz ===== Implementar tu propio Context Manager ===== class Saved(): def __init__(self, cr): self.cr = cr def __enter__(self): self.cr.save() return self.cr def __exit__(self, type, value, traceback): self.cr.restore() cr.translate(68, 68) for i in xrange(6): with Saved(cr): cr.rotate(2 * math.pi * i / 6) cr.rectangle(-25, -60, 50, 40) cr.stroke() ===== Ejecutar comandos y leer ===== Ejecuta el comando, mostrando su salida, y devuelve un int. import os os.system('ls -l') import os stream = os.popen('echo Returned output') output = stream.read() output ===== Crear procesos ===== Crear un proceso y leer lo que sale por pantalla: >>> a = subprocess.check_output('ls') >>> a b'alpine.tar\napps\nbin\nbuild\ncbf_git.txt\ncoma_git.txt\ndbcompare.venv\nDesktop\ndist\nDocuments\nDownloads\nexample.retry\nexample.yml\nfabfile.py\nflowRoot884.png\ngitea.dockerfiles\ngitea.tar\njenkins_home\nlogo2.png\nlogo2_small.png\nmanage.py\nMusic\nnew-repo\nPictures\n-proxy\nPublic\nREADME.md\nrema\nrequirements.txt\nresources\nscript.py\nTemplates\ntmp\nVideos\nvoid\nworkspace\nWorkspace\n' The same but not using a bytestring: >>> print(subprocess.check_output('ls', universal_newlines=True)) alpine.tar apps bin build cbf_git.txt coma_git.txt dbcompare.venv Desktop dist ... Since running ''ls -l'' is that ''ls'' is the command, and ''-l'' is a flag to that command. >>> print(subprocess.check_output(['ls', '-l'], universal_newlines=True)) total 103160 -rw------- 1 alfred alfred 5801472 Apr 8 14:46 alpine.tar drwxrwxr-x 9 alfred alfred 4096 Apr 29 15:49 apps drwxrwxr-x 3 alfred alfred 4096 Dec 18 14:33 bin drwxrwxr-x 4 alfred alfred 4096 Apr 29 15:49 build -rw-rw-r-- 1 alfred alfred 880 Jan 14 10:34 cbf_git.txt ... To tell Python to pass the parameters through the UNIX shell so it accepts special characters: print(subprocess.check_output(['ls', '-l', '*.txt'], shell=True, universal_newlines=True)) ''subprocess.run'' takes many similar arguments to subprocess.check_output. But what's different is that it doesn't return a string, even when universal_newlines is set to True. Instead, it returns an instance of subprocess.CompletedProcess, which contains all sorts of information about the process that ran. >>> subprocess.run(['/bin/ls', '-l'], universal_newlines=True, stdout=subprocess.PIPE) >>> vars(cp) {'args': ['/bin/ls', '-l'], 'returncode': 0, 'stderr': None, 'stdout': None} You also can assign stderr to subprocess.PIPE in order to receive it. Note that in the case of both stdout and stderr, you can assign not just subprocess.PIPE, which lets you grab and work with the program's output, but also an open (writable) file object. This means you can invoke an external process and put its output into an arbitrary file. I'd argue that most of the time, the reason you would be executing an external process in Python is that you want to do something to the text, but this will work. You might be wondering whether you can not only write to stderr and stdout, but also read from stdin. And the answer is definitely. Just provide a file object, and subprocess.run will do the rest. For example: >>> cp = subprocess.run(['/bin/cat', '-n'], stdin=open('/etc/passwd'), stdout=subprocess.PIPE, universal_newlines=True) ===== SETS ===== >>> my_set = set("patata") >>> my_set {'p', 't', 'a'} >>> united_set = first_set.union(second_set) >>> united_set {'two', 'banana', 'three', 'peach', 'orange', 'one'} ... >>> first_set = {'one', 'two', 'three'} >>> second_set = {'orange', 'banana', 'peach', 'one'} >>> first_set.intersection(second_set) {'one'} ... >>> first_set = {'one', 'two', 'three'} >>> second_set = {'three', 'four', 'one'} >>> first_set.difference(second_set) {'two'} >>> second_set.difference(first_set) {'four'}