sys

Описание: Программирование на супер модном мега крутом языке Питон.

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#1 dyvniy » Вт, 24 марта 2015, 12:17:52

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = '[Python@localhost]# '
[Python@localhost]# print 'Ой!'
Ой!
[Python@localhost]#

Для разработки пакетов вещ незаменимая! Позволяет не обновлять версию пакета после правок.

Код: Выделить всё

python setup.py develop
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#2 dyvniy » Вт, 24 марта 2015, 12:19:02

Информация о поиске модулей.

Код: Выделить всё

import sys
sys.path.append('PyQt4')
sys.path.append('PyQt4/wig')
print sys.path
Когда вы импортируете модуль, то Питон ищет файл с таким именем не где-нибудь, а в определённых каталогах. Эти каталоги определены в переменной окружения PYTHONPATH вашей операционной системы. Эта переменная имеет структуру, схожую с переменной PATH и так же содержит в себе каталоги, где Питон будет искать модули. При отсутствии этой переменной, Питон будет искать модули в папке, куда были установлены его исполняемые файлы, а так как этот каталог зависит от инсталляции и частенько никаких модулей в нём нет, то удалять или изменять без особой необходимости PYTHONPATH не следует. Доступ к списку каталогов поиска можно получить также из списка sys.path модуля sys(import sys). Этот список можно изменять программно, путём стандартных операций со списками. Ни в коем случае не называйте свои модули так же, как названы стандартные модули Питона, так как это повлечёт за собой труднообнаружимую ошибку. Если подлежащий импорту скрипт находится в том же каталоге, что и вызывающая его программа, то нет необходимости обращаться к sys.path, так как Питон ищет модули также и в текущей директории.
http://citforum.ru/programming/python/python3.shtml
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#3 dyvniy » Ср, 1 апреля 2015, 18:45:49

Пример ускорения python используя ctypes
http://www.py-my.ru/post/50997be0bbddbd2f44000002#!
Спойлер
Один из вариантов ускорить выполнение кода Python - переписать медленный метод на язык C, с помощью ctypes можно подключать библиотеки написанные на C.
Ниже пример вызова C-метода и сравнение производительности.

1) Пишем метод (файл myfib.c)
unsigned long fib(unsigned long x)
{
if(x < 2) return x;
return fib(x-1) + fib(x-2);
}

2) Компилируем:
gcc -shared -Wl,-soname,myfib.so -o myfib.so -fPIC myfib.c

3) Вызываем из Python и сравниваем с функцией написанной на чистом python:
import ctypes
import timeit

fib = ctypes.CDLL('./myfib.so').fib
fib.restype = ctypes.c_long
fib.argtypes = (ctypes.c_ulong,)

print(timeit.timeit('fib(32)', 'from __main__ import fib', number=1))

def pyfib(x):
if x < 2: return x
return pyfib(x-1) + pyfib(x-2)

print(timeit.timeit('pyfib(32)', 'from __main__ import pyfib', number=1))

Результат:
0.0463268756866
1.08009696007

В итоге, за счет использования ctypes, мы получили ускорение в 23 раза.

Если использовать оптимизацию при компиляции, то можно получить большую производительность, для этого нужно указать ключ оптимизации:
gcc -O3 -shared -Wl,-soname,myfib.so -o myfib.so -fPIC myfib.c

Варианты ключей оптимизации:
-O1 - Базовая оптимизация
-O2 - GCC выполняет почти все поддерживаемые оптимизации, эта опция уменьшает как время компиляции так и время выполнения сгенерированного кода.
-O3 - Более сильная оптимизация, включает -O2 + некоторые дополнительные опции.

С учетом оптимизации -O3, мы получили такой результат:
0.023335695266
1.08294892311

Это быстрее в 46 раз чем на чистом python.

Описание ctypes на сайте питона
https://docs.python.org/2/library/ctypes.html
Спойлер
типы
ctypes type C type Python type
c_bool _Bool bool (1)
c_char char 1-character string
c_wchar wchar_t 1-character unicode string
c_byte char int/long
c_ubyte unsigned char int/long
c_short short int/long
c_ushort unsigned short int/long
c_int int int/long
c_uint unsigned int int/long
c_long long int/long
c_ulong unsigned long int/long
c_longlong __int64 or long long int/long
c_ulonglong unsigned __int64 or unsigned long long int/long
c_float float float
c_double double float
c_longdouble long double float
c_char_p char * (NUL terminated) string or None
c_wchar_p wchar_t * (NUL terminated) unicode or None
c_void_p void * int/long or None
15.17.1.17. Callback functions
Спойлер
ctypes allows to create C callable function pointers from Python callables. These are sometimes called callback functions.

First, you must create a class for the callback function, the class knows the calling convention, the return type, and the number and types of arguments this function will receive.

The CFUNCTYPE factory function creates types for callback functions using the normal cdecl calling convention, and, on Windows, the WINFUNCTYPE factory function creates types for callback functions using the stdcall calling convention.

Both of these factory functions are called with the result type as first argument, and the callback functions expected argument types as the remaining arguments.

I will present an example here which uses the standard C library’s qsort() function, this is used to sort items with the help of a callback function. qsort() will be used to sort an array of integers:

>>>
>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)
>>> qsort = libc.qsort
>>> qsort.restype = None
>>>
qsort() must be called with a pointer to the data to sort, the number of items in the data array, the size of one item, and a pointer to the comparison function, the callback. The callback will then be called with two pointers to items, and it must return a negative integer if the first item is smaller than the second, a zero if they are equal, and a positive integer else.

So our callback function receives pointers to integers, and must return an integer. First we create the type for the callback function:

>>>
>>> CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
>>>
For the first implementation of the callback function, we simply print the arguments we get, and return 0 (incremental development ;-):

>>>
>>> def py_cmp_func(a, b):
... print "py_cmp_func", a, b
... return 0
...
>>>
Create the C callable callback:

>>>
>>> cmp_func = CMPFUNC(py_cmp_func)
>>>
And we’re ready to go:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), cmp_func)
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
>>>
We know how to access the contents of a pointer, so lets redefine our callback:

>>>
>>> def py_cmp_func(a, b):
... print "py_cmp_func", a[0], b[0]
... return 0
...
>>> cmp_func = CMPFUNC(py_cmp_func)
>>>
Here is what we get on Windows:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), cmp_func)
py_cmp_func 7 1
py_cmp_func 33 1
py_cmp_func 99 1
py_cmp_func 5 1
py_cmp_func 7 5
py_cmp_func 33 5
py_cmp_func 99 5
py_cmp_func 7 99
py_cmp_func 33 99
py_cmp_func 7 33
>>>
It is funny to see that on linux the sort function seems to work much more efficiently, it is doing less comparisons:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), cmp_func)
py_cmp_func 5 1
py_cmp_func 33 99
py_cmp_func 7 33
py_cmp_func 5 7
py_cmp_func 1 7
>>>
Ah, we’re nearly done! The last step is to actually compare the two items and return a useful result:

>>>
>>> def py_cmp_func(a, b):
... print "py_cmp_func", a[0], b[0]
... return a[0] - b[0]
...
>>>
Final run on Windows:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func))
py_cmp_func 33 7
py_cmp_func 99 33
py_cmp_func 5 99
py_cmp_func 1 99
py_cmp_func 33 7
py_cmp_func 1 33
py_cmp_func 5 33
py_cmp_func 5 7
py_cmp_func 1 7
py_cmp_func 5 1
>>>
and on Linux:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func))
py_cmp_func 5 1
py_cmp_func 33 99
py_cmp_func 7 33
py_cmp_func 1 7
py_cmp_func 5 7
>>>
It is quite interesting to see that the Windows qsort() function needs more comparisons than the linux version!

As we can easily check, our array is sorted now:

>>>
>>> for i in ia: print i,
...
1 5 7 33 99
>>>
Note Make sure you keep references to CFUNCTYPE() objects as long as they are used from C code. ctypes doesn’t, and if you don’t, they may be garbage collected, crashing your program when a callback is made.
Also, note that if the callback function is called in a thread created outside of Python’s control (e.g. by the foreign code that calls the callback), ctypes creates a new dummy Python thread on every invocation. This behavior is correct for most purposes, but it means that values stored with threading.local will not survive across different callbacks, even when those calls are made from the same C thread.

Код: Выделить всё

fib = ctypes.CDLL('./myfib.so').fib
fib
.restype = ctypes.c_long
fib
.argtypes = (ctypes.c_ulong,) 


Компилируем:
Linux:

Код: Выделить всё

gcc -shared -Wl,-soname,myfib.so -o myfib.so -fPIC myfib.c

Windows:

Код: Выделить всё

cl /DLL /o main.dll main.c

в коде __declspec(dllexport) перед функцией
Вложения
C_callback_in_python.zip
(18.08 КБ) 112 скачиваний
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#4 dyvniy » Вт, 23 июня 2015, 11:35:10

Использование COM объектов. Пока Excel но думаю с DirectX можно так же.

Код: Выделить всё

import win32com.client Excel win32com.client.Dispatch("Excel.Application"

http://savepearlharbor.com/?p=232291#com
Спойлер
Работа с com-объектом

В своих отчетах я предпочитаю использовать второй способ, а именно использование файла Excel через com-объект с использованием библиотеки win32com. Его преимуществом, является то, что вы можете выполнять с файлом все операции, которые позволяет делать обычный Excel с использованием VBA.

Проиллюстрируем это на той же задаче, что и предыдущие примеры.

Для начала загрузим нужную библиотеку и создадим COM объект.

import win32com.client Excel = win32com.client.Dispatch("Excel.Application")

Теперь мы можем работать с помощью объекта Excel мы можем получить доступ ко всем возможностям VBA. Давайте, для начала, откроем любую книгу и выберем активный лист. Это можно сделать так:

wb = Excel.Workbooks.Open(u'D:\\Scripts\\DataScience\\ArticleScripts\\ExcelPython\\xl.xls') sheet = wb.ActiveSheet

Давайте получим значение первой ячейки и последовательности:

#получаем значение первой ячейки val = sheet.Cells(1,1).value #получаем значения цепочки A1:A2 vals = [r[0].value for r in sheet.Range("A1:A2")]

Как можно заметить, мы оперируем здесь функциями чистого VBA. Это очень удобно если у вас есть написанные макросы и вы хотите использовать их при работе с Python при минимальных затратах на переделку кода.

Посмотрим, как можно произвести запись полученных значений:

#записываем значение в определенную ячейку sheet.Cells(1,2).value = val #записываем последовательность i = 1 for rec in vals: sheet.Cells(i,3).value = rec i = i + 1 #сохраняем рабочую книгу wb.Save() #закрываем ее wb.Close() #закрываем COM объект Excel.Quit()

Из примера видно, что данные операции тоже довольно просто реализовываются. Кроме этого, можно заметить, что изменения мы сохранили в той же книге, которую открыли для чтения, что достаточно удобно.

Однако, внимательный читатель, обратит внимание на переменную i, которая инициализируется не 0, как принято python, а 1. Это связано с тем, что мы работаем с индексами ячеек как из VBA, а там нумерация начинается не с 0, а с 1.

Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#5 dyvniy » Ср, 26 августа 2015, 16:00:22

Case в питоне

Код: Выделить всё

def f(x):
    return {
        
'a'1,
        
'b'2,
    }[
x
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#6 dyvniy » Ср, 2 марта 2016, 15:33:39

Сборщик мусора можно выключить!
https://docs.python.org/3.3/library/gc.html#gc.disable
http://stackoverflow.com/questions/20495946/why-disable-the-garbage-collector
gcold = gc.isenabled()
gc.disable()
Спойлер
Why disable the garbage collector?

up vote
10
down vote
favorite
2
Pythons gc.disable disables automatic garbage collection. As I understand it, that would have quite some side-effects. Why would anyone want to disable automatic garbage collection, and how could one effectively manage memory without it?

python garbage-collection
shareimprove this question
asked Dec 10 '13 at 13:32

gerrit
2,57511544
add a comment
4 Answers
active oldest votes
up vote
12
down vote
accepted
One use for disabling the garbage collector is to get more consistent results when timing the performance of code. The timeit module does this.

def timeit(self, number=default_number):
if itertools:
it = itertools.repeat(None, number)
else:
it = [None] * number
gcold = gc.isenabled()
gc.disable()
...
In Python2 and up to Python3.2 gc.disable() is also used to avoid a bug caused by garbage collection occurring between fork and exec. The problem seems to have been fixed in Python3.3 without needing to call gc.disable().

shareimprove this answer
edited Dec 16 '13 at 23:16
answered Dec 10 '13 at 13:34

unutbu
336k40592728
add a comment
up vote
5
down vote
From the same page you link to:

Since the collector supplements the reference counting already used in Python, you can disable the collector if you are sure your program does not create reference cycles.
So that answers the second part of the question, "how could one effectively manage memory without it". Don't create reference cycles. It's a fairly limited use case, sure.

For the first part of the question the answer is performance. Again, a fairly limited use case.

Disabling GC would only help if (a) the GC is actually doing work, and (b) that work is achieving nothing, that is to say it's finding nothing to free, or finding so little that you think your program can tolerate the leak for as long as GC is disabled. So, if your program is too slow and doesn't create reference cycles and disabling GC appears to speed it up, then you would consider disabling GC.

I speculate (based on previous GC that I've seen, not Python's in particular) that if you don't allocate any memory then the garbage collector won't have any long-term performance cost. It might have some short-term and unpredictable cost tidying up what has gone before. So even in the case where you're going into a massive numpy number-crunching routine and think you should look to squeeze all possible performance out of that part of the code, disabling GC while you do it still wouldn't help. It will just delay the time cost of tidying up previous reference cycles until after you re-enable GC.

Arguably, programs that run for a short time and don't use much memory do not need garbage collection, they can tolerate leaks. But even more arguably, if you start out thinking like that you will eventually get into trouble with a program that leaks more memory than you expected.

shareimprove this answer
edited Dec 10 '13 at 13:52
answered Dec 10 '13 at 13:35

Steve Jessop
193k19278527
add a comment
up vote
3
down vote
Another use-case would be to manually control the garbage collection with gc.collect()

shareimprove this answer
answered Dec 10 '13 at 13:35

James Mills
11.1k21934

But is disabling the GC first a requirement to be able to use gc.collect()? Or what is a use-case for gc.collect()? (note: I actually had such use case in the past in a C# application that went out of memory on a <512MiB box) – phresnel Dec 10 '13 at 13:36

No. You can call gc.collect() any any time AFAIK. – James Mills Dec 10 '13 at 13:36
add a comment
up vote
3
down vote
The problem with an enabled GC always is that you do not know when it will happen. So if (a part of) your program is time-critical, needs real-time, etc., then you can disable the GC for the time (that part of) your program runs.

Whether you want to switch the automatic GC on again later or if you prefer to do it manually by calling gc.collect() is of no concern to that question.

Also, some programs are designed to run only a very short time, so that maybe the developer can assure that there cannot occur any memory problem during that time (consider programs like ls); then that whole GC aspect can be neglected in favor of performance.
Изображение


Название раздела: Python
Описание: Программирование на супер модном мега крутом языке Питон.

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Python»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 8 гостей