Контакты

Достижения

Все достижения (3)

Наибольший вклад в теги

Все теги (11)

Лучшие ответы пользователя

Все ответы (18)
  • Зачем в python range() если есть xrange()?

    Kademn
    @Kademn
    Злой
    Сначала было слово и слово было Python... бла бла бла....
    А потом добавили range, который создавал всю последовательность натуральных чисел в памяти и это было хорошо, так как можно было их итерировать.
    А потом добавили xrange, который не добавлял весь набор в памяти, а вычислял следующий элемент, ничего не зная про остальные (предыдущие и последующие элементы), почти ничего не занимая в памяти. Так появились генераторы. И поняли, что генераторы это хорошо, отделили генераторы от итераторов и стало так.
    А потом Девид Бизли на Пайконе 2008, высеченными на камне презентациями... ой я увлекся.
    Ответ написан
    Комментировать
  • Как авторизоваться на сайте с помощью python?

    Kademn
    @Kademn
    Злой
    Подозреваю, что вам необходимо использовать requests.Session()
    url = 'https://...'
    login = 'login'
    password = 'password'
    s = requests.Session()
    r = s.get(url, auth=(login, password))


    Раз вы взялись использовать какую-то библиотеку, начните с чтения документации к этой библиотеке, обычно там есть ответы на большинство ваших вопросов.
    Тут например

    Еще, зачастую, чтение чужого кода помогает понять как правильно (или неочень) пользоваться тем или иным инструментом. Скрипт авторизующийся в вконтакте и качающий музыку пишет, пожалуй, каждый начинающий питонщик. Найти несложно.
    Немало также статей по парсингу сайтов с помощью python. В них непременно будет urllib или requests. Например тут.
    Вообщем, ищите и обрящете =)
    Вот и в результате послал в гугл, мда. =)

    upd. Раз вы самообучаетесь для себя, попробуйте порешать задачи тут: checkio.org. Полезнее всего будет не просто решать задачи, а смотреть как ту же задачу решили другие, много нового для себя откроете и цели в виде решения очередной задачи всегда будут иметься (ачивки, если вы искушенный задрот, тоже самоцель). В примерах оставленными другими есть как хорошо документированные, так и безумные решения завернутые в одну строку.
    Ответ написан
    3 комментария
  • Сколько памяти займет скрипт на питоне?

    Kademn
    @Kademn
    Злой
    Список хранит ссылки на переменные в памяти, а значит список длиной N в 32-х битных системах будет иметь размер (2*2)*N, а в 64-х битных (4*2)*N
    >>> from sys import getsizeof
    
    >>> l = list()
    >>> print getsizeof(l)
    32 (в 32 битной системе)
    64 (в 64 битной системе)

    Значит искомая величина 32 + (2*2)*N (в 32 битной системе), 64 + (4*2)*N (в 64 битной системе), где N - длина списка.
    Но список хранит указатели, а значит место займут еще и сами данные. В вашем случае данные имеют тип integer
    >>> from sys import getsizeof as gs
    >>> a = int()
    >>> print gs(a)
    12 (в 32 битной системе)
    24 (в 64 битной системе)

    Значит памяти всего израсходуется
    32 + (2*2)*N + N*12 (в 32 битной системе)
    64 + (4*2)*N + N*24 (в 64 битной системе)

    Для списка из 7млн чисел имеем:
    32 + (2*2)*7000000 + 7000000*12 = 112000032 байт = 109375 Кбайт = 106.8 Мбайт
    64 + (4*2)*7000000 + 7000000*24 = 224000064 байт = 218750 Кбайт = 213.6 Мбайт
    Ответ написан
    Комментировать
  • Правильное отображение прогрессбара на Python - что не так?

    Kademn
    @Kademn
    Злой
    Давайте по-порядку.
    Вот участок кода, отвечающий за прогресс-бар:
    for i in range(lenLi):
        sys.stdout.write('\r')
        sys.stdout.write("[%-30s] %d%%" % ('='*i, i))
        sys.stdout.flush()

    Во-первых вывод в консоль у вас неправильный. Длина вашего прогресс-бара 30 символов. Значит при каждой итерации нужно выводить количество символов, соответствующее итерации, не забывая, что нельзя выводить дробное количество символов. К примеру, если длина списка у вас 5, значит 30/5=6 символов добавляет каждая итерация цикла. Но вы переписываете весь прогресс-бар, поэтому можно посчитать "часть" от всей длины (30 символов) для этого шага. Например для длины 5, шаг 1 - это 1/5 длины, шаг 2 это 2/5 длины и т.д. Тогда количество символов это количество символов для "полной" длины умножить на полученную часть.
    part = float(i)/(lenLi-1)
    symbols_num = int(30 * part)

    lenLi -1, так как выше вы увеличивали длину на единицу (видимо для range), то тогда range стоило бы начинать с 1, а не с нуля. А проценты легко получить умножив part на 100, не забыв сменить форматирование вывода с '%s%%' на, скажем, '%3.2f%%', так как в выводе дробное число и оно очень плохо смотрится, если %s.
    Теперь прогресс-бар будет выводиться правильно:
    for i in range(1, lenLi):
        sys.stdout.write('\r')
        part = float(i)/(lenLi-1)
        symbols_num = int(30 * part)
        sys.stdout.write("[%-30s] %3.2f%%" % ('='*symbols_num, part*100))
        sys.stdout.flush()

    Правда, чтобы успеть увидеть изменения, добавьте в цикл wait(), иначе все 100% заполнятся за доли секунды.
    UPD
    Да, вы для каждой ссылки заполняете прогресс-бар от нуля до 100 процентов. Цикл внутри цикла не нужен. Прогресс-бар должен быть частью for x in li:. Но, для правильного отображения прогресс-бара, вам необходимо считать номер шага. Для это можно либо завести переменную, которая будет считать шаги, либо использовать функцию enumerate:
    for step_number, x in enumerate(li):
    Учитывая, что вам удобнее нумеровать шаги с единицы, правильнее было бы использовать
    for step_number, x in enumerate(li, 1):
    А вообще, если вы хотите использовать прогресс-бар и в других местах кода, то стоило бы завести отдельную функцию для печати прогресса, которая принимает дробное число от 0 до 1 или процент в качестве аргумента и выводит в консоль соответствующий прогресс-бар, возвращая каретку в начало строки.
    Полагаю, что этих подсказок более, чем достаточно. Дальше попробуйте сами.
    Ответ написан
    3 комментария
  • Каким образом у разных объектов оказывается общим один параметр?

    Kademn
    @Kademn
    Злой
    Дело в том, что переменная `calls` объявлена в классе и ее наследуют все экземляры этого класса. И у них у всех, при создании, self.calls указывает на одно и тоже место в памяти, на оду и ту же переменную. Так как переменная в памяти это изменяемый объект, изменяя его в любом из экземпляров, вы видите измененный объект в любых других экземплярах, да и в самом классе тоже.
    Если хотите, чтобы при создании экземпляра создавался новый объект в памяти, а не наследовался указатель, используйте __init__, который вызывается при создании экземпляра.
    class SubClass(object):
        def __init__(self):
            self.calls = set()


    Кстати сказать, что с классом SomeClass у вас абсолютно таже история. Изменяемый объект (словарь param), указатель на который наследуют все экземпляры.
    Ответ написан
    3 комментария