[Python-es] namespaces y variables globales

jordi torrents jtorrents en milnou.net
Vie Nov 5 13:35:29 CET 2010


Alvaro, Chema y Ramiro,

Gracias por insistir. Contesté a Ramiro sin hacer pruebas y me
equivoqué. La solución que propusieron Alvaro, Ramiro y Chema (y
otros) es la más adequada para solucionar mi problema. Ahora me queda
un poco mas claro cómo gestionar las variables globales y el
funcionamento de los namespaces. De hecho voy a hacer varios cambios
en mis scripts de cálculo utilizando un módulo para todas las
variables globales tal cómo habeis sugerido.

En mi defensa tengo que decir que no soy programador (soy sociólogo) y
utilizo python básicamente para hacer análisis de redes complejas. Así
que algunas cosas se me escapan y las voy aprendiendo sobre la marcha.
Sin duda hoy he aprendido algo ;)

Pego a continuación un ejemplo un poco largo de utilización de
parallelpython (para instalarlo en Debian: sudo aptitude install
python-pp) para ilustrar cómo crear la instancia de pp.Server en la
función main utilizando el número de cpus pasado al script via línea
de comandos (en este ejemplo no uso un módulo aparte para las
variables globales por brevedad, pero lo voy a hacer en mis programas
de cálculo a parir de ahora).

Gracias a todos y Salut!

----------------test.py---------------
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import math, sys, time
from optparse import OptionParser
import pp

job_server = ''

def get_job_server(ncpus,ppservers):
    return pp.Server(ncpus=ncpus,ppservers=ppservers)

def isprime(n):
    """Returns True if n is prime and False otherwise"""
    if not isinstance(n, int):
        raise TypeError("argument passed to is_prime is not of 'int' type")
    if n < 2:
        return False
    if n == 2:
        return True
    max = int(math.ceil(math.sqrt(n)))
    i = 2
    while i <= max:
        if n % i == 0:
            return False
        i += 1
    return True

def sum_primes(n):
    """Calculates sum of all primes below given integer n"""
    return sum([x for x in xrange(2,n) if isprime(x)])

def test_parallel(inputs):
    start_time = time.time()
    jobs = [(input, job_server.submit(sum_primes,(input,),\
        (isprime,), ("math",))) for input in inputs]
    for input, job in jobs:
        print "Sum of primes below", input, "is", job()

    print "Time elapsed using parallelization: ", time.time() - start_time, "s"

def test_sequential(inputs):
    start_time = time.time()
    for input in inputs:
        print "Sum of primes below", input, "is", sum_primes(input)

    print "Time elapsed without using parallelization: ", time.time()
- start_time, "s"

def main():
    parser = OptionParser()
    parser.add_option('-t','--run_test', action='store_true', dest='run', \
        help='Run test',default=False)
    parser.add_option('-n', '--ncpus', help='Number of CPUS to use',
dest='ncpus', \
        action='store', type='int', default=None)
    options, args = parser.parse_args()

    ppservers=()

    if not options.ncpus:
        ncpus = "autodetect"
    else:
        ncpus = options.ncpus

    global job_server
    job_server = get_job_server(ncpus,ppservers)

    inputs = (100000, 200000, 300000, 400000, 500000, 600000)

    if options.run:
        print "Runing in parallel:"
        test_parallel(inputs)
        print "Runing sequentially:"
        test_sequential(inputs)

if __name__ == '__main__':
   main()
----------------------------------------

El resultado en un Core2Duo:
jtorrents en jupiter:~/tests$ ./test.py -t -n 2
Runing in parallel:
Sum of primes below 100000 is 454396537
Sum of primes below 200000 is 1709600813
Sum of primes below 300000 is 3709507114
Sum of primes below 400000 is 6458901531
Sum of primes below 500000 is 9914236195
Sum of primes below 600000 is 14071826345
Time elapsed using parallelization:  18.2996480465 s
Runing sequentially:
Sum of primes below 100000 is 454396537
Sum of primes below 200000 is 1709600813
Sum of primes below 300000 is 3709507114
Sum of primes below 400000 is 6458901531
Sum of primes below 500000 is 9914236195
Sum of primes below 600000 is 14071826345
Time elapsed without using parallelization:  28.0983469486 s


Más información sobre la lista de distribución Python-es