
Проксимов
09.04.2017
10:51:10
Zart, это ты
Ого

Zart
09.04.2017
10:51:37

Nikolay
09.04.2017
10:51:44

Google

Zart
09.04.2017
10:52:03
ну... когда они нужны - это становится самоочевидно

melancholiac
09.04.2017
10:52:35

Max
09.04.2017
10:52:39
Чат, почему когда я на джанге портирую в urls
url(r'^$', views.index, name='index')
Он ругается на unersolved reference? Я уже добавил папку с проектом в add source roots to PYTHONPATH in Python Console

Nikolay
09.04.2017
10:52:49

melancholiac
09.04.2017
10:53:49
так вот эта cli тулза и запускает основной скрипт + делает всякое полезное

Артем
09.04.2017
10:54:39

melancholiac
09.04.2017
10:54:55
я переносил весь католог венва на другую машину, но там была ошибка что не найдет этот самый скрипт

Zart
09.04.2017
10:55:02
одно из популярных применений классметодов - конструкция экземпляров класса:
class Foo:
@classmethod
def from_list(cls, *args):
obj = cls()
obj.data = args
return obj
foo = Foo.from_list(1, 2, 3, 4) # <__main__.Foo object at 0x03020A10>
class Bar(Foo):
pass
bar = Bar.from_list(1, 2, 3, 4) # <__main__.Bar object at 0x03020A50>
как видим на примере - подклассы автоматом получают тот же метод, но создают экземпляр не родителя, а себя
обычный метод не подходит, потому что вызывается на уже созданном объекте
статик не пройдет потому что не знает к какому классу вообще относится
венвы копировать нельзя. там есть хак с virtualenv --relocatable venv но работает он паршиво и не для этого

Nikolay
09.04.2017
10:58:17
Смысл на примерах вроде понятен, как и в других статьях в интернете, но подробного объяснения не нашел. Отбросим staticmethod, вот есть функция в классе, как определить, делать ли ее classmethod или обычным методом?

Zart
09.04.2017
10:58:31

Google

melancholiac
09.04.2017
10:59:00

Zart
09.04.2017
10:59:16

melancholiac
09.04.2017
10:59:50

Zart
09.04.2017
11:00:13
один из вариантов. другой - создать сдист и перенести его

Nikolay
09.04.2017
11:00:26

Zart
09.04.2017
11:00:41
если исходники под контролем версий - можно перенести им

melancholiac
09.04.2017
11:01:11
где я мог ошибиться тут?

Zart
09.04.2017
11:01:50
вот тот фромлист можно вызвать и на foo.from_list(1, 2, 3)
при этом сам экземпляр foo игнорируется, в расчет берется лишь его класс

melancholiac
09.04.2017
11:02:04
utils - cli тулза
мейн - основной скрипт

Zart
09.04.2017
11:02:30

melancholiac
09.04.2017
11:03:10
но ругается на этапе pip install

Zart
09.04.2017
11:03:34
ок... покажи свой setup.py?

melancholiac
09.04.2017
11:04:10
извини что фото

Zart
09.04.2017
11:05:07
это работать не будет

Google

Zart
09.04.2017
11:05:26
за /yafr/main.py в py_modules вообще яйца отрывать надо

Nikolay
09.04.2017
11:05:32

melancholiac
09.04.2017
11:05:36
умвр на моес компьютере

Zart
09.04.2017
11:05:52
сетап описывает твои исходники
у тебя есть модуль утилс и пакадж яфр
py_modules=['utils'],
packages = ['yafr'],
но раз у тебя сетаптулз уже, то лучше делать проще
from setuptools import setup, find_packages
setup(
....
packages = find_packages(),
....
)

melancholiac
09.04.2017
11:07:41

Zart
09.04.2017
11:07:55
если utils занимается тупым импортом и запуском yafr.main, то я бы его выкинул и оставил бы
entry_points = {
'console_scripts': ['utils = yafr.main:main'],
}
тогда pip install бы создал utils.exe автоматом и оно бы запускалось без вопросов

melancholiac
09.04.2017
11:09:09

Zart
09.04.2017
11:09:40
а что мешало вынести это в пакадж?

melancholiac
09.04.2017
11:10:03

Zart
09.04.2017
11:10:07
не понял
почему бы не вынести этот код из utils.py в yafr.main?
а если yafr/main.py переименовать в yafr/__main__.py то его станет можно запускать через python -m yafr

melancholiac
09.04.2017
11:11:24
в utils.py я использую click
т.е. это топ левел скрипт
имо так удобнее намного, чем держать код для того чтоб дропать дб в том же файле что и основной код

Google

melancholiac
09.04.2017
11:13:58
(просто так было в flask туторе)

Zart
09.04.2017
11:15:43
за что люди так любят (ана/мини)конду?...

Maxim
09.04.2017
11:19:39
за то что проблем со сборкой нету - это виртуаленв но без нервов. хотя смотря какие пакеты ставить там тоже многих нету

Zart
09.04.2017
11:21:32
если бы авторы собирали бинарные пакеты, то у обычного питона тоже бы проблем не было

Maxim
09.04.2017
11:22:35
ну ща почти все пакеты в хиле идут... но это токо новые, когда пайп новый выйдет тоже х3 что будет может они вообще скажут что токо wheel

Nikolay
09.04.2017
11:24:33
теперь очевидно когда нужен классметод? 8)
Более-менее. Есть некоторые мелочи, которые нужно осмыслить, но уже картина яснее. Ну вот, допустим, в __init__ есть self.my_variable = self.get_my_variable(args), т.е. при создании объекта вызывается метод get_my_variable, который произведет какие-то вычисления и вернет значение в self.my_variable. Правильно ли здесь использовать self? Если нужен доступ к этим вычислениям в каком-то другом месте, то не вызывая объект, можно же сделать get_my_variable классметодом и в __init__ заменить на self.my_variable = MyClass.get_my_variable(args)?

Zart
09.04.2017
11:25:20
вдобавок ты хардкодишь имя класса в конкретном __init__
впрочем внутри обычных методов всегда можно узнать свой собственный класс (если он например унаследован) через type(self) или self.__class__

Nikolay
09.04.2017
11:27:00

Zart
09.04.2017
11:27:43
нет, в унаследованном классе селф.__класс__ будет ссылаться на дочерний
это кстати причина по которой super нужно кормить имя текущего класса явно
и ни в коем случае не self.__class__

Nikolay
09.04.2017
11:29:53
Т.е. переменная не в __init__, а в классе самом.

Zart
09.04.2017
11:30:22
это немного бессмысленно
если мы читаем - то self.myvar будет работать почти так же, если только не перекрыта инстансом
self.foo - ищет сперва foo в слотах и self.__dict__
если не находит, то идёт по иерархии классов и проверяет классовые переменные
Parent.foo, GrandParent.foo, object.foo

Nikolay
09.04.2017
11:32:03
это немного бессмысленно
Там в переменной загружается словарь с помощью json, а метод использует эту переменную. Ведь если в методе загружать этот словарь, то при каждом вызове он будет загружаться снова, хотя я сам немного не допер до логики того, кто писал этот код.

Zart
09.04.2017
11:32:25
так обычно кэш организовывают

Google

Zart
09.04.2017
11:32:39
выносят на уровень класса, чтобы был общим для всех экземпляров класса

><
09.04.2017
11:32:43
Господа, а при создании коннекта к sqlite , автоматом создается файлик названиебд.db?

Zart
09.04.2017
11:33:12
если подключаешься к inmemory базе - то нет
или если прав не хватит

Nikolay
09.04.2017
11:33:28

Zart
09.04.2017
11:33:48
помним что объявление класса - само по себе объект
со своим набором переменных

Nikolay
09.04.2017
11:35:00

Zart
09.04.2017
11:35:49
foo = Foo() - фу у нас экземпляр класса Фу
но при этом класс Фу - это экземпляр класса type
а type - это экземпляр класса type
мета!
но при этом type унаследован от object, который в корне вообще всего и вся

Nikolay
09.04.2017
11:37:21
Там подгружается словарь из json на уровне класса, метод использует этот словарь. Но теперь ясно, что в этом есть смысл, потому что экземпляры класса там создаются постоянно во время работы программы, но каждый экземпляр берет данные из этого словаря для своих целей.
По сути это же то же самое, что и хранить этот словарь где-то вне класса или импортировать из другого модуля и вызывать mymodule.переменная, но, как я понимаю, эффективнее там вызывать self.__class__.переменная в каждом объекте класса, потому что вне класса и его объектов переменная не задействована?


Zart
09.04.2017
11:39:44
>>> class Foo:
... cache = {}
...
... def caching(self, key, val):
... self.cache[key] = val
...
>>>
>>> obj1 = Foo()
>>> obj2 = Foo()
>>>
>>> obj1.caching(1, 1)
>>> obj2.caching(2, 2)
>>>
>>> print(obj1.cache, obj2.cache, Foo.cache)
({1: 1, 2: 2}, {1: 1, 2: 2}, {1: 1, 2: 2})
>>> print(obj1.cache is obj2.cache is Foo.cache)
True
подклассы будут пользоваться тем же кэшем в данном случае

Nikolay
09.04.2017
11:40:58
Эта группа больше не существует