сдуру связался с python :(

pitrik2

3 дня уже на этом языке
первый день компилял
второй день изучал язык и писал попутно код
накатал 415 строчек
а третий день начал желать большего и питон мне этого не дал :(
коллеги говорят на руби переходить пока не поздно
работать будет медленнее зато проблем не будет
проблемы:
0. непонятно как вызывать сишные функции, т.к. библиотека ctypes падает в корку на солярисе
1. __dict__ не содержит аттрибуты класса объявленные в заголовке класса, __dict__ не содержит аттрибуты потомка,
я уж было решил всю инициализацию в __init__ загнать, дык метод super работает как next а не как super, такое использовать стрёмно - потом аукнется
заюзал пока что __getattribute__ но он не даёт список всех аттрибутов
2. лямбды уродские
3. нет карринга
4. нет DSL
вот терь думаю, переходить на руби или нет
плюсы питона:
1. весь язык учится за один день
2. мега простой синтаксис - нужно чтобы моим кодом другие коллеги пользовались не особо вникаясь
3. куча вещей в нем есть, а вдруг в руби не будет? например
- создание класса по стрингу
- импорт модуля по стрингу
- потоки, блокирующие очереди, прикольная штука Event
- есть универсальный конструктор в одну строчку:

def __init__(self, **kw):
self.__dict__.update(kw)

4. говорят руби сильно медленнее питона
P.S.
в руби есть афигенная функция next у стрингов
как в питоне ее написать?
щас я сделал генератор мотающий от AAA0001 до ZZZ9999, когда приходит строчка я отматываю генератор до нее и потом беру следующее значение
но это же изврат :(
генератор и моталка:

def _idGenerator:
for word in itertools.product(itertools.product(string.uppercase, repeat = 3
itertools.product(string.digits, repeat = 4:
yield ''.join(word[0]) + ''.join(word[1])
def next(str):
idGenerator = _idGenerator
while idGenerator.next != str : pass
return idGenerator.next

ava3443

0. непонятно как вызывать сишные функции, т.к. библиотека ctypes падает в корку на солярисе
а dbx на что? где падает - смотрели?
собираете всё одним компилятором, с одним и тем же рантаймом?

psihodog

первый день компилял
я пять лет делала мужчинам маникюр. а вчера узнала, что это называется не "маникюр"!

:grin:
чего ты там компилял? :)

psihodog

0. непонятно как вызывать сишные функции, т.к. библиотека ctypes падает в корку на солярисе
если сишных функций не много, то написать модуль к питону на сях.
1. __dict__ не содержит аттрибуты класса объявленные в заголовке класса, __dict__ не содержит аттрибуты потомка,
потому что __дикт__ содержит атрибуты инстанса а не класса.
я уж было решил всю инициализацию в __init__ загнать, дык метод super работает как next а не как super
чего-чего?
заюзал пока что __getattribute__ но он не даёт список всех аттрибутов
что такое "список аттрибутов"?
попробуй dir
2. лямбды уродские
может и уродские, главное удобные.
в чём проблема?
3. нет карринга
есть карринга =)
4. нет DSL
не знаю... наверно такое как Deemon демонстрировал сделать не получится.

yroslavasako

проблемы:
0. непонятно как вызывать сишные функции, т.к. библиотека ctypes падает в корку на солярисе
1. __dict__ не содержит аттрибуты класса объявленные в заголовке класса, __dict__ не содержит аттрибуты потомка,
я уж было решил всю инициализацию в __init__ загнать, дык метод super работает как next а не как super, такое использовать стрёмно - потом аукнется
заюзал пока что __getattribute__ но он не даёт список всех аттрибутов
2. лямбды уродские
3. нет карринга
4. нет DSL
0. тоже не знаю. Ты уверен, что руби будет корректно вызывать си либы под соляркой? Вообще проблема кажется довольно обыкновенной - постройка гетерогенной системы под специфичную платформу. Как правило решается (нужно перебрать все возможные варианты взаимного применения компилеров и интерпретеров)
1. У тебя какая версия языка? в старых классы нужно наследовать от object. Вообще заботай data model - классы в питоне устроены достаточно сложно и они не вполне классы. __dict__ не должен их содержать, их нужно искать в __class__. __dict__ - это обычный дикт, если потом проинициализировал аттрибуты, то они там лежат.
В принципе Data Model питона достаточно гибкая - можно сделать всё что душа пожелает, а если не хватает, то есть метатипы, декораторы и в самом крайнем случае - рефлексия.
2. А что не так? Что они однострочные? Так для многострочных подпрограмм есть def. У лямбд есть одна проблема, что в третий версии, что во второй - динамическое связывание.
3. Карринг есть (отдельной либой) а ещё можешь посмотреть functools.partial
4. DSL - а что это такое и зачем нужно?

karkar

Если есть jvm, попробуй jruby. Он по скорости где-то на уровне перла, не намного медленнее питона.
Про связь руби с сишными функциями не подскажу, но народ байндинги клепает вагонами, значит все не очень сложно. Недавно вот с wxRuby имел дело (байндинг к wxWidgets очень доволен остался.
В плане легкости изучения и чтения не думаю, что руби сильно сложнее питона. Но консистентней и красивее, имхо.
- создание класса по стрингу
- импорт модуля по стрингу

А как же.
потоки, блокирующие очереди, прикольная штука Event

Потоки, которые threads, есть, но зеленые. В классическом интерпретаторе есть global interpreter lock, который не дает им исполнятся действительно параллельно. В jruby, кажется, иначе.
универсальный конструктор в одну строчку

Несложно написать.

pitrik2

2. А что не так? Что они однострочные? Так для многострочных подпрограмм есть def. У лямбд есть одна проблема, что в третий версии, что во второй - динамическое связывание.
я не вижу в них вообще смысла
проще def написать строчкой выше
в других языках лямды во-первых удобно записываются (например без длиннющего слова лямда вначале во-вторых они в карринг выстраиваются
здесь для карринга предлагается обёртки использовать и скобки (как в перле) опускат ьнельзя при вызове функций
вощем по-уродски всё

pitrik2

jruby
не
это не подходит
джавы нет и связываться с ней не охота

pitrik2

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

print a.x # ok
print a.__dict__['x'] # тут у питона может а может и не быть exception

karkar

Неохота jruby, бери любой другой (MRI - 1.8, yarv - 1.9, RubyEE - 1.8, но пошустрее и с меньшим потреблением памяти). 1.9 быстрее и моднее, чем 1.8, но там кое от чего отказались, например от продолжений (callcc afaik.

tipnote

При всем уважении.
Если после собственноручной сборки у тебя что-то падает в корку - повод поискать, че не так собрал в первую очередь, а во вторую пенять на языковое окружение
Если после дня изучения питона ты залез в __dict__ вместо inspect и __getattribute__ вместо getattr, то мне кажется, что питон не подходит под твои задачи. Или как минимум под твой способ чтения документации или изучение языка. Мне страшно предположить, что у тебя с читабельностью кода.
По ощущениям, у вас не срастется, надо срочно убегать с питона.

psihodog

даж не знаю что на это отвечать
учите матчасть
:lol:
какую матчасть?
"Что я имел ввиду" by в пяти томах издание исправленное и дополненное?
:grin:
поясни, что ты пишешь, что получаешь и что хочешь.
мне это непонятно, даж по-другому скажу: я не хочу этого понимать
у тебя сейчас фаза отрицания.
скоро будут понимание и боль :grin:
print a.x # ok
print a.__dict__['x'] # тут у питона может а может и не быть exception
а что тут не работает?
a.x — это так ты по-питоньи говоришь, я хочу получить аттрибут x объекта a
a.__dict__['x'] — я хочу значение соответствующее ключу 'x' в похожем на словарь аттрибуте __dict__ объекта a
по счастливой случайности, стандартные классы имплементированы так, что иногда объекты возвращаемые в этих двух случаях совпадают.
но это далеко не всегда так. открой для себя слоты, а ещё всякие проксирующие классы. там __dict__ вообще может не быть.

yroslavasako

это не подходит
джавы нет и связываться с ней не охота
ебать, как из соляры можно было выпилить яву? Она там чуть ли не в ядро частично встроена

yroslavasako

Про связь руби с сишными функциями не подскажу, но народ байндинги клепает вагонами, значит все не очень сложно. Недавно вот с wxRuby имел дело (байндинг к wxWidgets очень доволен остался.
для питона народ тоже байндинги клепает вагонами. Под традиоционными ОС и gcc. А тут вопрос про весьма специфичную платформу

pitrik2

Если после дня изучения питона ты залез в __dict__ вместо inspect и __getattribute__ вместо getattr, то мне кажется, что питон не подходит под твои задачи. Или как минимум под твой способ чтения документации или изучение языка. Мне страшно предположить, что у тебя с читабельностью кода.
изучал я питон по вот этой штуке: http://docs.python.org/tutorial/classes.html
собсна это первое что выдает гугл
__dict__ там на каждом углу, а вот про inspect я от тебя ща впервые услышал
в __getattribute__ меня послал гугл, который сказал что это из питона 3 и надо это юзать
не понял наезд про читабельность
я как бы помешан на этом и слежу чтобы она всегда была приличной

tipnote

>изучал я питон по вот этой штуке: http://docs.python.org/tutorial/classes.html
>собсна это первое что выдает гугл
>__dict__ там на каждом углу, а вот про inspect я от тебя ща впервые услышал
Гм? Там два упоминания о __дикт__ и ни одного примера его использования.
>в __getattribute__ меня послал гугл, который сказал что это из питона 3 и надо это юзать
Хз как он тебя послал, скорее ты пошел. __ методы - служебные, сделанные для переопределения, а не вызова. Это как вместо оператора + использовать __add__
>не понял наезд про читабельность
>я как бы помешан на этом и слежу чтобы она всегда была приличной
Использование подчерк методов и атрибутов превращает код в слабочитаемый. А использование __дикт__ я бы вообще классифицировал, как хак.

rosali

1. весь язык учится за один день
дальше не стал читать. ты искренне веришь что существует язык который учится за один день? с++ и тот только за 21...

Dasar

>дальше не стал читать. ты искренне веришь что существует язык который учится за один день? с++ и тот только за 21...
а что действительно есть используемые языки, которые за день не учатся?

okis

с++ и тот только за 21...
если с нуля, опытный программист может гораздо быстрее освоиться

bleyman

> а что действительно есть используемые языки, которые за день не учатся?
Ну как бы с одной стороны питон например действительно учится за день — до уровня, когда ты можешь править чужие скрипты и писать несложные свои, без каких-либо жутких сюрпризов. Например, в плюсах есть момент когда осознаёшь, что все эти невиртуальные деструкторы, которые ты успел написать, НЕ РАБОТАЮТ. В питоне такого нет.
С другой стороны я наконец начал понимать как на самом деле работает ОО в Питоне через год или два после того, как овладел им в достаточном для комфортного использования объёме.

yroslavasako

для описания всего этого разнообразия опций придумали два слова: "кривая обучения". За эталон можно взять изучение vi

pitrik2

Использование подчерк методов и атрибутов превращает код в слабочитаемый. А использование __дикт__ я бы вообще классифицировал, как хак.
идет вторая неделя
читаю штуки типа: http://doc.openerp.com/contribute/15_guidelines/coding_guide...
так и не понимаю в for, if и т.п нужно ли ставить пробел перед двоеточием?
все __getattribute__ заменил на getattr
оказалось что универсальный конструктор можно сделать еще универсальнее:

def universalCtr(self, args, kw):
for arg in args:
try:
self.__dict__.update(arg)
except (ValueError, TypeError):
raise NameError('Unsupported argument passed: <%s>' % str(arg
self.__dict__.update(kw)

class A:
def __init__(self, *args, **kw):
utils.universalCtr(self, args, kw)

смысл в том что можно теперь сколько угодно dict передавать
если dict один, то можно использовать его разворачивание в kwargs: A(**d)
но если их два то питон ругается: A(**d1, **d2)
с новым конструтором роблема решена: A(d1, d2)
P.S.
ворчать всё равно не перестаю, но уже реже
недавно вот оказалось что у Popen нету join с таймаутом
пришлось написать кривой воркэраунд:

def waitProcess(p, timeout):
finish = time.time + timeout
while p.poll is None and time.time < finish :
time.sleep(1)

yroslavasako

мне всё упонее кажется, что пишешь сериализацию на коленке

pitrik2

мне всё упонее кажется, что пишешь сериализацию на коленке
сериализацию?
чего?

tipnote

Во-первых, мне непонятно, нахрена городить такое в принципе, а во-вторых, манипуляции над классом или его методами делаются через метакласс или декоратор, и __дикт__ в манипуляциях не участвует. Еще раз, перед тем, как использовать __ метод или атрибут убедись, что это _действительно_ необходимо. Потому что в твоем коде потом черт ногу сломит, а сам он, вполне вероятно, будет ломаться от версии к версии питона.

shlyumper

Почитай http://learnpythonthehardway.com/index или http://diveintopython.org/toc/index.html, что больше попрет.
На первые 3 месяца программирования забудь про существование методов, в имени которых есть более одного символа _ (с одним исключением: __init__).
P.S. Твой код (бестолковый, по-моему, ну да ладно переписаный на чем-то, более напоминающем питон, чем хаки:

def melearnpython(self, args, kwargs):
for arg in list(args) + [kwargs]:
try:
for k, v in arg.iteritems:
setattr(self, k, v)
except AttributeError:
raise NameError('Unsupported argument passed: %s' % repr(arg

Такой код работает правильно даже если в классе есть слоты, дескрипторы и прочая х-ня нестандартная.

pitrik2

Во-первых, мне непонятно, нахрена городить такое в принципе, а во-вторых, манипуляции над классом или его методами делаются через метакласс или декоратор, и __дикт__ в манипуляциях не участвует.
нахрена? ну удобно же очень
фактически класс = dict с методами

# у dict есть конструктор
d = {'a': 1, 'b': 2}
print d['a']

# а у классов конструктора нету, я им этот конструктор сделал
d = D({'a': 1, 'b': 2})
print d.a

# или еще удобнее
d2 = D(a=1, b=2)
print d.a

# вместо того как предлагает стандартный язык
d2 = D
for e in d1:
setattr(d2, e)
d.a = 10
d.c = 3
print d.a, d.b, d.c

# у меня
d2 = D(d1, a=10, c=3)
print d.a, d.b, d.c

везде в их стайлах написано, что читабельность кода очень важна
имхо, мой вариант гораздо короче, выразительнее, читабельнее
и даже читабельнее стандартного dict: меньше закорючек
по поводу __
ну нельзя их вообще не использовать
например как ты обходишься без __init__?
по поводу __dict__
у меня в коде это единственное место где он используется
можно вместо него for и setattr написать, но это же лишний код
что такое метаклассы и декораторы не знаю
стоит ли читать что это такое? как оно мне жизнь облегчит?
они мой универсальный конструктор заменят?

pitrik2

На первые 3 месяца программирования забудь про существование методов, в имени которых есть более одного символа _.
тот же вопрос
как обойтись без __init__?

pitrik2

for arg in list(args) + [kwargs]:
в стайл гайде питоновском написано что надо использовать chain вместо +
ибо + порождает новый список, а chain ленивый ибо генератор
:)

shlyumper

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" --- D. Knuth.
P.S. Еще читай import this до просветления. ;)

shlyumper

фактически класс = dict с методами
Низачот. http://docs.python.org/reference/datamodel.html. Еще гуглить слова slots, descriptors

pitrik2

Низачот. http://docs.python.org/reference/datamodel.html. Еще гуглить слова slots, descriptors
странные вы
сначала говорите про __ забыть
потом отсылаете туда где практически только __
слоты, дескрипторы - не понимаю зачем мне это
также как лямбды, конструкция есть, но нафига нужна непонятно
потом, я это говорил не про классы конкретно, я ж даже про наследование не сказал
а про то как я их в основном использую
да и по твоей ссылке написано что атрибуты класса это dict
кстати
зачем ты str на repr заменил?
в эксепшен как раз логичнее же str кидать

tipnote

нахрена? ну удобно же очень
фактически класс = dict с методами
code:
# у dict есть конструктор
d = {'a': 1, 'b': 2}
print d['a']
# а у классов конструктора нету, я им этот конструктор сделал
d = D({'a': 1, 'b': 2})
print d.a
# или еще удобнее
d2 = D(a=1, b=2)
print d.a
# вместо того как предлагает стандартный язык
d2 = D
for e in d1:
    setattr(d2, e)
d.a = 10
d.c = 3
print d.a, d.b, d.c
# у меня
d2 = D(d1, a=10, c=3)
print d.a, d.b, d.c
Во-первых, как тебе намекнули, __дикт__ и атрибуты совершенно необязательно взаимосвязаны.
Во-вторых, ты на питоне пытаешься нафигачить какой-то новый, тебе одному понятный язык. И это офигенная проблема. Потому что я совершенно не ожидаю, что переданный словарь станет атрибутами.
В-третьих, сама задача если и имеет смысл, то только там, где используются реально не столько классы, сколько словари, то есть в класс передаются тонны слабообрабатываемых в рамках класса данных. Хотя даже тут скорей ожидал, что у класса будет атрибут-словарь, куда все это г и польется. Зачем для этого нужен класс - х тебя з. Нормальные параметры, передаваемые в конструктор имеют тенденцию к обработке - проверке, конвертации в другие, более удобные формы данных, группировке и проч и проч.
В-четвертых (на деле в продолжении в-третьих использование передачи параметров в конструктор через словарь, а-ля A(**d) нормально выглядит либо в машиночитаемом коде, либо в служебном коде, в который они уже переданы именно так (декораторы, как пример либо если параметры в структуру собираются непосредственно (пусть и относительно долго) перед передачей в конструктор. В остальных случаях мне очень-очень сильно захочется оторвать руки автору, когда я полезу искать, какое же значение передается (и передается ли) через этот словарь
везде в их стайлах написано, что читабельность кода очень важна
имхо, мой вариант гораздо короче, выразительнее, читабельнее
и даже читабельнее стандартного dict: меньше закорючек
Короче и непонятней. Однострочники мощные любишь?
по поводу __
ну нельзя их вообще не использовать
например как ты обходишься без __init__?
Инит ты переопределяешь (не вызываешь напрямую, не модифицируешь снаружи, не тупо переназначаешь у представителя класса и так далее (все это иногда приходится делать, но нужно только тогда, когда ты все четко в питоне и в своей задаче уяснил) ) - следовательно используешь по назначению. В рамках модели питона все ок. Практический смысл инита - конструктор, поэтому этот служебный метод стоит несколько особняком в использовании.
по поводу __dict__
у меня в коде это единственное место где он используется
можно вместо него for и setattr написать, но это же лишний код
Сетатрр безопасней и универсальней. Надеюсь, понятно? Тебе уже намекали на всякие __слотс__
что такое метаклассы и декораторы не знаю
стоит ли читать что это такое? как оно мне жизнь облегчит?
они мой универсальный конструктор заменят?
Это встроенные языковые средства модификации поведения классов, методов и проч снаружи этих самых классов-методов-проч. Вообще новичка в питоне к ним подпускать нельзя, но у тебя и так все пестрит... пусть уж хотя бы будет нормально реализовано.

tipnote

странные вы
сначала говорите про __ забыть
потом отсылаете туда где практически только __
слоты, дескрипторы - не понимаю зачем мне это
также как лямбды, конструкция есть, но нафига нужна непонятно
потом, я это говорил не про классы конкретно, я ж даже про наследование не сказал
а про то как я их в основном использую
да и по твоей ссылке написано что атрибуты класса это dict
Тебя отослали читать и курить, что такое классы и какие они бывают, а не бросаться использовать то, что написано. Судя по последней фразе ты читал выборочно.
Про нужно - не нужно. Гвидо очень трепетно относится к расширению языковых конструкций (поэтому некоторые вещи очевидно урезаны и если что-то в питоне появилось, значит, иначе просто уже нельзя было.

tipnote

Кстати, к вопросу в первом посте треда. Если первое, что ты делаешь, это пытаешься в общем "улучшить" язык вместо решения прикладных задач, то может реально надо поискать другой язык, который и так удовлетворит?

pitrik2

В-третьих, сама задача если и имеет смысл, то только там, где используются реально не столько классы, сколько словари, то есть в класс передаются тонны слабообрабатываемых в рамках класса данных. Хотя даже тут скорей ожидал, что у класса будет атрибут-словарь, куда все это г и польется. Зачем для этого нужен класс - х тебя з. Нормальные параметры, передаваемые в конструктор имеют тенденцию к обработке - проверке, конвертации в другие, более удобные формы данных, группировке и проч и проч.
нафига проверка?
в стайл гайде написано что надо меньше проверять, что например не надо смотреть на тип параметра а надо сразу бабахать его использовать: типа тип того что передали будет не тот но использоваться он сможет нормально
да и потом, если проверку аргументов вводить и вводить конкретный список аттрибутов у каждого класса - то нафига тогда динамические языки использовать? с++, джава, с# - полно языков с более строгими проверками
пп атрибута словаря: ну дык тогда через точку нельзя будет значения присваивать, доставать
неужели тебе и вправду понятнее "msg.dict['type'] = 1" вместо "msg.type = 1" ?
пп тонн данных
ну вот например у меня есть класс Config
с помощью модуля argparse я параметры командной строки засовываю в этот класс
потом в разных модулях я делаю import config и использую config.Config чтобы узнать тот или иной параметр
разные модули имеют разные параметры, эти модули потом разные люди писать будут
перечислять всевозможные аттрибуты в Config? да я задолбаюсь это делать, сейчас у меня класс Config - это три строчки
а так будет огромадный файл
что если 2 разных модуля придумаю параметр с одним именем но разным смыслом?
ну дык как я уже говорил: это питон а не джава
нужно быть постоянно начеку

pitrik2

Кстати, к вопросу в первом посте треда. Если первое, что ты делаешь, это пытаешься в общем "улучшить" язык вместо решения прикладных задач, то может реально надо поискать другой язык, который и так удовлетворит?
ну шок от "сырости" языка уже прошел
наверна я просто не привык к "меняющимся" языкам, что с++, что джава, что хаскель, что перл - там спеки кучу лет назад приняли и не меняли, а тут на каждом шагу так делайте, так больше не делайте, так потом делайте
разработка ведется довольно быстро, но самое главное вполне читабельно чтобы другим людям давать
с корками пока смирился, в ихней багзилле собсна так и пишут, что запускать питон на соляре 64бит только на свой страх и риск
собсна я наверна потом на линукс и перейду

pitrik2

Про нужно - не нужно. Гвидо очень трепетно относится к расширению языковых конструкций (поэтому некоторые вещи очевидно урезаны и если что-то в питоне появилось, значит, иначе просто уже нельзя было.
странная фраза
это про джаву так говорят, там по нескольку лет мусолят добавлять изменение в язык или нет
а питона версий вона целая куча
такое ощущение что тама куча бестолковых контрибутчиков
одни решили что надо все функции работы со строками в модуль strings сунуть
а другие решили, что в сами строки
третьи же любители побазарить, всякие там пропозалы фигачат: типа давайте reduce уберем, она не нужна никому

shlyumper

Тебя отослали читать, а не писать. Для понимания сути проблемы, вот тебе твой оригинальный суперконструктор, и пример того, как он не работает вообще:

def universalCtr(self, args, kw):
for arg in args:
try:
self.__dict__.update(arg)
except (ValueError, TypeError):
raise NameError('Unsupported argument passed: <%s>' % str(arg
self.__dict__.update(kw)

class A(object):
def __init__(self, *args, **kw):
universalCtr(self, args, kw)

a = A(x=1, y=2)
print a.x, a.y

class B(object):
__slots__ = ['x', 'y']
def __init__(self, *args, **kw):
universalCtr(self, args, kw)

b = B(x=1, y=2)
print b.x, b.y

shlyumper

везде в их стайлах написано, что читабельность кода очень важна
имхо, мой вариант гораздо короче, выразительнее, читабельнее
и даже читабельнее стандартного dict: меньше закорючек
Похоже, все, что тебе нужно было - это не суперконструктор, а что-то вроде класса типа такого: http://github.com/webpy/webpy/blob/master/web/utils.py#L47
В отличие от суперконструктора, такой класс еще и dict'ом по-прежнему остается ;)

tipnote

нафига проверка?
в стайл гайде написано что надо меньше проверять, что например не надо смотреть на тип параметра а надо сразу бабахать его использовать: типа тип того что передали будет не тот но использоваться он сможет нормально
да и потом, если проверку аргументов вводить и вводить конкретный список аттрибутов у каждого класса - то нафига тогда динамические языки использовать? с++, джава, с# - полно языков с более строгими проверками
Йоптвою, чего ты привязался к проверке _типа_. Очевидно, я имел ввиду логическую проверку, "бизнес логику", твоя программа кроме записывания атрибутов что-то полезное вообще делает?
пп атрибута словаря: ну дык тогда через точку нельзя будет значения присваивать, доставать
неужели тебе и вправду понятнее "msg.dict['type'] = 1" вместо "msg.type = 1" ?
Причем тут точка вообще. Мне непонятна логика с передачей в качестве _одного_из_ параметров словаря, который потом магическим образом разворачивается в словарь атрибутов. Если что-то сгруппировано в словарь, значит, на то есть причина, а в конструкторе словарь либо обработают, вытащив, если нужно что-то в атрибуты, либо сохранят. Вот что предполагаю я.
Если нужен атрибут тайп - он будет _явно_ объявлен в конструкторе. Как вообще с твоим классом работать, блин, узнавать набор его атрибутов непосредственно перед обращением? Как вообще можно считать, что твой код после этого стал читабельнее, если ты все что можно делаешь неявно.
Если тебе нужен словарь с точкой - пронаследуй словарь и переопредели механизм работы с атрибутами. По крайней мере для других это будет что-то с понятным значением.
пп тонн данных
ну вот например у меня есть класс Config
с помощью модуля argparse я параметры командной строки засовываю в этот класс
потом в разных модулях я делаю import config и использую config.Config чтобы узнать тот или иной параметр
разные модули имеют разные параметры, эти модули потом разные люди писать будут
перечислять всевозможные аттрибуты в Config? да я задолбаюсь это делать, сейчас у меня класс Config - это три строчки
а так будет огромадный файл
что если 2 разных модуля придумаю параметр с одним именем но разным смыслом?
ну дык как я уже говорил: это питон а не джава
нужно быть постоянно начеку
сейчас я лезу в settings.py (и меня при этом не колышет, как он заполняется - руками, командной строкой или чем там еще - меня это _не_интересует_) и смотрю, а что же можно настроить в этом приложении - и мне все очевидно (ну или очевиднее)
перечитай import this на тему явного-неявного.

pitrik2

Похоже, все, что тебе нужно было - это не суперконструктор, а что-то вроде класса типа такого: http://github.com/webpy/webpy/blob/master/web/utils.py#L47
В отличие от суперконструктора, такой класс еще и dict'ом по-прежнему остается ;)
о
первый действительно дельный ответ
, ты супер!
ты заодно ответил на вопрос который был еще в первом посте: как список всех аттрибутов класса получить
я могу безболезненно от него наследоваться?
мне же нужно еще чтобы методы были в "моих классах"
ну и потом там метод storify отдельно
а мне надо чтобы он конструктором был

pitrik2

сейчас я лезу в settings.py (и меня при этом не колышет, как он заполняется - руками, командной строкой или чем там еще - меня это _не_интересует_) и смотрю, а что же можно настроить в этом приложении - и мне все очевидно (ну или очевиднее)
ты специально не пытаешься меня понять?
ну нет у меня физической возможности в Config перечислить все возможные случаи
список аттрибутов у меня узнается опцией -h командной строки, это автоматически делает argparse
Как вообще с твоим классом работать, блин, узнавать набор его атрибутов непосредственно перед обращением?
эээ
ты же сам в этот класс кладешь, сам и забираешь
ошибешься в имени: получишь стандартный питоновский AttributeError
вот еще пример
вчера коллега захотел справочник завести
вот его код без моего конструктора:

class Client:
isBroker = True
isTrusted = False
def __init__(self, **kwargs):
if hasattr(kwargs, 'isBroker'):
self.isBroker = kwargs['isBroker']
if hasattr(kwargs, 'isTrusted'):
self.isTrusted = kwargs['isTrusted']

TRUSTED = Client(isTrusted = True)

# использование моего фреймворка
msg = Msg(Type = 'Client', isBroker = TRUSTED.isBroker, isTrusted = TRUSTED.isTrusted)
sendMessage(msg)

вот с моим конструктором

class Client:
isBroker = True
isTrusted = False
def __init__(self, *args, **kw):
utils.universalCtr(self, args, kw)

TRUSTED = Client(isTrusted = True)

# использование моего фреймворка
msg = Msg(Type = 'Client', isBroker = TRUSTED.isBroker, isTrusted = TRUSTED.isTrusted)
sendMessage(msg)

дальше я проапгрейдил свой конструктор чтобы он dict-ы принимал и код стал еще проще:

Client = {
'isBroker': True,
'isTrusted': False
}
TRUSTED = dict(Client, isTrusted = True)

# использование моего фреймворка
msg = Msg(Type = 'Client', client)
sendMessage(msg)

неужели вы всерьез хотите сказать что надо использовать первый вариант?
там в описании класса имя каждого аттрибута аж 4 раза встречается
не напоминает ли вам это ужас с++?

pitrik2

Тебя отослали читать, а не писать. Для понимания сути проблемы, вот тебе твой оригинальный суперконструктор, и пример того, как он не работает вообще:
и чо ты мне этот пример написал?
я его по твоему не понимаю что ли?
я же говорю, что раз я слоты не использую (а вы мне пока не сказали зачем мне их использовать) то и париться по этому поводу нечего
потом, ты же сам мне написал вариант более правильного конструктора
я его уже даже успел в свой код вставить

shlyumper

вот еще пример
вчера коллега захотел справочник завести
вот его код без моего конструктора:
...
вот с моим конструктором
Ебануться. Кто-нибудь из вас понимает разницу между

class X:
attr = blah

и

class X:
def __init__(self):
self.attr = blah

Ну и наконец, вот как этот код ДОЛЖЕН был быть написан:

class Client(object):
def __init__(self, isBorker=True, isTrusted=False):
self.isBroker = isBroker
self.isTrusted = isTrusted

Чтобы не искать потом, почему вот этот код работает странно:

TRUSTED = Client(is_Trusted = True)

shlyumper

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

pitrik2

Ебануться. Кто-нибудь из вас понимает разницу между
эээ
разница в том что одно попадает в __dict__ а другое нет?

yroslavasako

эээ
разница в том что одно попадает в __dict__ а другое нет?
одно - член класса, другое - член объекта. Член класса - аналог статика для этого класса.

pitrik2

Ну и наконец, вот как этот код ДОЛЖЕН был быть написан:

class Client(object):
def __init__(self, isBorker=True, isTrusted=False):
self.isBroker = isBroker
self.isTrusted = isTrusted

Чтобы не искать потом, почему вот этот код работает странно:

TRUSTED = Client(is_Trusted = True)
в твоем ДОЛЖЕН каждый аттрибут указывается три раза
это НЕУДОБНО
что если у класса 20 аргументов? ты задолбаешься их все так описывать
и потом хрен найдешь у какого аргумента какое дефолтное значение
в моем же варианте все значения в столбик вначале класса
можно к каждому значению доку написать, можно их группировать с помощью пустой строки

class Client:
''' something meaningful ''
isBroker = True
''' something meaningful ''
isTrusted = False

''' seconf group of attribs ''
isTrusted = False

Чтобы не искать потом, почему вот этот код работает странно:

TRUSTED = Client(is_Trusted = True)
на эту тему думал
придумал такое решение:

def universalCtr(self, args, kw, strict = True):
for arg in list(args) + [kw]:
try:
for k, v in arg.iteritems:
if strict and not hasattr(self, k):
raise NameError('Strict mode disallow passing unknown attributes: %s' % repr(k
setattr(self, k, v)
except AttributeError:
raise NameError('Unsupported argument passed: %s' % repr(arg

pitrik2

одно - член класса, другое - член объекта. Член класса - аналог статика для этого класса.
блин
ребят
ну не надо меня за дибила держать
зачем пишите очевидные вещи?
или вы хотите сказать что в следующей версии питона
class A:
attr = 5
a = A
print a.attr
будет падать?
и поэтмоу нельзя члены класса использовать для задания дефолтовых значений для членов инстанса?

yroslavasako

блин
ребят
ну не надо меня за дибила держать
зачем пишите очевидные вещи?
ты же сказал, что они различаются только вхождением в __dict__ Вот я и написал, что различие более глобальное - одно изменяется вместе с каждым объектом класса, а второе - одно для всех объектов одного класса.

tipnote

ты специально не пытаешься меня понять?
ну нет у меня физической возможности в Config перечислить все возможные случаи
список аттрибутов у меня узнается опцией -h командной строки, это автоматически делает argparse
Ох, блин. Пойдем с другой стороны, где и кем проводится валидация конфига, где и кем хранятся дефолтные значения необязательных параметров? Хоть этот кто-то знает все возможные случаи? Или ничего не проверяется, пока где-то в глубине других модулей не вылетает эксепшн недопустимого значения, и все дружно лезут по цепочке, пытаясь понять, где испорчено значение параметра?
Ладно, мне похоже реально непонятна специфика многомодульного приложения с тонной неопределенных опций, передаваемых через командную строку. Ок.
эээ
ты же сам в этот класс кладешь, сам и забираешь
ошибешься в имени: получишь стандартный питоновский AttributeError
я - другой разработчик, который в силу разных причин полез разбираться в твоем коде. Я ничего туда не кладу и не забираю. Я пытаюсь понять логику работы приложения.
code:
Client = {
'isBroker': True,
'isTrusted': False
}
TRUSTED = dict(Client, isTrusted = True)
# использование моего фреймворка
msg = Msg(Type = 'Client', client)
sendMessage(msg)
Я с трудом понимаю, где профит. То ли первый чел использовал класс как структуру в си и следовательно, да, нужно было словарь, то ли у тебя в Мсг происходит что-то, чего мне не видно

#примем, что
class Msg(object):
def __init__(self, client):
#process client

#работа через статику
class Client(object):
isBroker = True
isTrusted = False
type = 'Client'

class TrustedClient(Client):
isTrusted = True

msg = Msg(client=TrustedClient)
sendMessage(msg)

#работа через инстанс

class Client(object):
def __init__(self, isBroker=True, isTrusted=False, **kwargs):
self.isBroker = isBroker
self.isTrusted = isTrusted
self.type = 'Client'

msg = Msg(client=Client(isTrusted=True
sendMessage(msg)

#работа через инстанс два
class Client(object):
def __init__(self, isBroker=True, isTrusted=False, **kwargs):
self.isBroker = isBroker
self.isTrusted = isTrusted
self.type = 'Client'

TrustedClient = functools.partial(Client, isTrusted=True)

msg = Msg(client=TrustedClient
sendMessage(msg)

неужели вы всерьез хотите сказать что надо использовать первый вариант?
там в описании класса имя каждого аттрибута аж 4 раза встречается
не напоминает ли вам это ужас с++?
ужас у меня вызывает желание сократить все и вся

tipnote

и поэтмоу нельзя члены класса использовать для задания дефолтовых значений для членов инстанса?
это неочевидная логика, увеличивающая вероятность неправильного использования, а следовательно ошибок
возможные ошибки:
обращение через имя класса
изменение значения через имя класса
разжевывать ошибки не надо?

yroslavasako

изменение значения через имя класса
всегда можно заюзать ограничение на readonly

pitrik2

о
вариант работы через статику с наследованием очень симпатичный
самый лаконичный из всех
вот только в Msg непонятно как его засовывать
ведь ты же опять извратил мою Msg
эта штука принимает "всё что угодно" и отправляет это по сети
в варианте со статикой мне надо уметь в конструкторе Msg вычитывать все атрибуты переданного класса

class Msg:
__init__(self, *args):
for class in args:
for attr, value in attrs(class):
internalDict[attr] = value

вот как бы еще эту attrs написать?

tipnote

Ты про __? Имхо, это bad practice в питоне

pitrik2

это неочевидная логика, увеличивающая вероятность неправильного использования, а следовательно ошибок
возможные ошибки:
обращение через имя класса
изменение значения через имя класса
> обращение через имя класса
тот кто так напишет сам дурак
когда ты пишешь чтото что потом предоставляешь другим (фреймфорк) то ты можешь попробовать уберечься от бестолкового дурака, но от умного дурака ты никогда не упасешься
кто обращается через имя класса - тот умный дурак
> изменение значения через имя класса
дык это же наоборот круто!
ща вот родилась такая идея: в папке configs лежат конфиги по имени юзера и машины:
user1.hostname1.py, user1.hostname2.py, user2.hostname1.py, ...
код в них примерно такой:

from config import *
TrustedClient.isTrusted = False

главная прога на старте берет из env $USER и $HOSTNAME и загружает соотв. конфиг

tipnote

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

tipnote

1) Если можно написать, не оставляя доп шанса на ошибку - стоит это делать при прочих равных
2) Очень круто.

class A:
msg = 'content'
a1 = A
....
#go deep in routines
A.msg = 'where the fuck is the content you expected on the top level'
b1 = A
...
#go up to the top level
aN = A
#process a1...aN and smile

shlyumper

эта штука принимает "всё что угодно" и отправляет это по сети
socket.send(pickle.dumps(my_supa_object
Так чтоле?

pitrik2

вот как бы еще эту attrs написать?
написал:

class Storage:
''' if class implements Storage then all its attribs will be processed in universalCtr '''
pass

def universalCtr(self, args, kw, strict = True):
def assign(self, k, v):
if strict and not hasattr(self, k):
raise NameError('Strict mode disallow passing unknown attributes: %s' % repr(k
setattr(self, k, v)

for arg in list(args) + [kw]:
if isinstance(arg, Storage):
for k,v in inspect.getmembers(arg, lambda x: not inspect.isroutine(x:
assign(self, k, v)
continue
if inspect.isclass(arg):
if issubclass(arg, Storage):
for k in filter(lambda x: not x.startswith('__') and not inspect.isroutine(getattr(arg, x dir(arg:
assign(self, k, getattr(arg, k
continue
try:
for k, v in arg.iteritems:
assign(self, k, v)
except AttributeError:
raise NameError('Unsupported argument passed: %s' % repr(arg

по результатам треда ввёл класс Storage
в доке к "моим хитрым конструкторам" написано что всё что они принимают будет разворачиваться
что принимать они могут: dict, kwargs, классы унаследованные от Storage, инстансы унаследованные от Storage

pitrik2

с корками пока смирился
он еще и сообщение перед коркой пишет
типа прикалывается:
Fatal Python error: PyString_InternInPlace: strings only please!
Abort (core dumped)
хотя чаще чтонить типа такого:
Assertion failed: gc->gc.gc_refs == GC_REACHABLE, file Modules/gcmodule.c, line 291
Abort (core dumped)
Оставить комментарий
Имя или ник:
Комментарий: