[This is my first post and I hope I have not completely misunderstood the use of SE - if so I apologize in advance]
I agree with "bgschaid" that the question is very difficult to answer based on the information provided. It makes a huge difference if you want low-level routines to exploit a multi-core architecture or if you need to exploit parallelism for embarrassingly parallel problems - or something in-between. An overview of different parallel computing possibilities in Python can be found here.
In the former case I for sure recommend to use tools such as NumPy / SciPy which at least in the MKL compiled version from Enthought supports multi-core architectures. Here you can control the number of cores to use via the environment variable "MKL_NUM_THREADS". This relies on highly optimized libraries that we can hardly expect to beat performance wise. I believe it is generally advised to use these high quality and highly optimized libraries whenever possible.
If you wish to exploit parallelism at a coarse level, the Python standard tool multiprocessing is easy to use - and it also supports shared data objects. There are different tools to use as part of the multiprocessing package. I have used map_async (SIMD like) and apply_async (MIMD like) for several problems with good results. The multiprocessing package is quite easy to use and being a standard part of Python means that you can expect other potential users of your code to easily be able to use it. multiprocessing also links to NumPy data objects directly. When using multiprocessing I would recommend you to set the environment variable "MKL_NUM_THREADS" to 1 such that NumPy is only allowed one core for each process/worker - otherwise you could end up in a resource contention between NumPy parallel and multiprocessing which leads to a performance degradation. multiprocessing works fine for a multi-CPU/multi-core architecture under the same operating system. I have used multiprocessing on a shared memory computer with 4 x Xeon E7-4850 CPUs (each 10 cores) and 512 GB memory and it worked extremely well. Shared arrays can be handled by multiprocessing.Array or sharedctypes. You can find the Python documentation here - check the library.pdf file. I have some slides explaining some of the basic parts of this - PM me if you want those.
If you have a cluster configuration with distributed memory I believe mpi4py is likely the preferred tool. I have not used this myself but I know that it is being used a lot in Python parallel programming.