Closed kc41 closed 6 years ago
Это пока proof-of-concept. В TODO'шках дописаны вещи, над которыми надо еще подумать, а так же доделать обратную совместимость с Python < 3.6.
Привет, идея хорошая, мне нравится. Если сохранится обратная совместимость, то будет вообще круто.
Ок, тогда как для старых питонов починю - переоткрою PR.
Надо понять что улучшает этот патч. Уменьшается размер кода и появляется проверка типов? По поводу размера, можно сделать как namedtuple
чтобы было покороче
class Ork(fact('Ork', 'first_name, last_name')):
...
По поводу проверки типов, ок, но на практике, вроде с этим не возникает проблем
Атрибуты бывают repeatable
, fact('Fact', [attribute('items').repeatable()])
, как это будет выглядеть? У атрибутов бывает значение по умолчанию fact('Fact', [attribute('day', 1), attribute('month', 1)])
. Это видимо будет day: str = 1
?
3 раза перечитал патч, ничё не понял, оч сложно, мне недоступны такие приёмы программирования на Питоне. Зачем _ROOT_FACT_DEFINITION
, BASE_FACT_DEFINITION_CLS
По поводу того, что улучшает данный патч:
Тут можно сделать следующее:
from typing import Iterable # Или более подходящий по семантике/методам класс или сделать свой
class Ork(FactDefinition): first_name: Iterable[str]
Если нужны будут совсем кастомные дескрипторы атрибутов:
```python
from yargy.typing import AttributeDescriptor # Или более подходящий по семантике/методам класс или сделать свой
class Ork(FactDefinition):
first_name: str = AttributeDescriptor(default_value="default_name", prop_1="val_1", prop_2=True)
Ну, метаклассы, они такие =) В стандартной библиотеке с NamedTuple (https://docs.python.org/3/library/typing.html#typing.NamedTuple) примерно так же сделано, как и в этом PR.
На данный момент, это PoC, реализованный на коленке за полчаса и сам я еще не очень хорошо знаком с библиотекой, но мне она очень понравилась) Я как раз хотел узнать, насколько мэйнтейнерам интересны подобные улучшения и услышать ваши комментарии на этот счет. Если интерес есть, то возьмусь более основательно)
Ещё вот что подумал: не все атрибуты класса должны быть полями факта. Например, есть факт Name
с полями first
, last
. У него есть атрибут icon
чтобы выводить данные в GUI
class Name(fact('Name', ['first', 'last'])):
icon = 'per.png'
...
icon
не извлекается из текста. В подходе с аннотациями поля факта и атрибуты класса перемешиваются, так?
В приведенном примере icon
останется полем класса. В __annotations__
попадают только строки вида some_name: some_expression
А так?
class Name(fact('Name', ['first', 'last'])):
icon: str = 'per.png'
...
А так - да попадет. В текущей реализации - берутся все имена аннотаций и передаются во второй аргумент функции fact()
в виде листа.
Можно подумать про такой вариант:
class Name(Fact):
__fact_attributes__ = ['first', 'last'] # потому что __attributes__ занято Record
icon = '...'
Но он не про твои улучшения "статический анализатор", "автокомплит"
Аннотации там сами по себе ничего не меняют. Это просто метки, которые оказываются в атрибуте __annotations__
у класса. Конструкция:
class A():
a: str
b: str = B()
Экливалентна следующему объявлению класса:
class A():
b = B()
__annotations__ = {"a": str, "b": str}
Подразумевается, что их будут обрабатывать в метаклассе (если обработку надо делать до создания класса) или декораторе над классом (если можно делать обработку после создания класса).
Всем привет.
Реализовал малоинвазивный способ объявлять классы фактов с использованием аннотаций типов из Py3.6. Вот пример, как при помощи этого способа создать класс факта.
Это будет эквивалент следующего: