All streams
Search
Write a publication
Pull to refresh
3
0
Adrian @ADR

Пользователь

Send message

Пример (парсер ест двойные пустые строки):


import types
from asyncio import QueueEmpty, QueueFull
from concurrent.futures import TimeoutError
from functools import wraps
from inspect import iscoroutinefunction

class ProcessException:
    __slots__ = ('func', 'custom_handlers')

    exclude = {
        QueueEmpty: lambda e: None,
        QueueFull: lambda e: None,
        TimeoutError: lambda e: None
    }

    def __init__(self, custom_handlers=None):
        self.func = None
        self.custom_handlers = custom_handlers

    def __call__(self, func):
        self.func = func

        if isinstance(self.custom_handlers, property):
            return self

        return self._get_wrapper()

    def __get__(self, instance, owner):
        setattr(owner, self.func.__name__, self._get_wrapper(instance, owner))

        return getattr(instance, self.func.__name__)  # return bounded method

    def _get_wrapper(self, instance=None, owner=None):
        if isinstance(self.custom_handlers, property):
            self.custom_handlers = self.custom_handlers.__get__(instance, owner)

        handlers = {
            **self.exclude,
            **(self.custom_handlers or {}),
            Exception: self._raise_exception
        }
        del self.custom_handlers

        if iscoroutinefunction(self.func):
            async def wrapper(*args, **kwargs):
                try:
                    return await self.func(*args, **kwargs)
                except Exception as e:
                    return handlers.get(type(e), handlers[Exception])(e)

        else:
            def wrapper(*args, **kwargs):
                try:
                    return self.func(*args, **kwargs)
                except Exception as e:
                    return handlers.get(type(e), handlers[Exception])(e)

        return wraps(self.func)(wrapper)

    @staticmethod
    def _raise_exception(e: Exception):
        raise e

class Math(object):
    def __init__(self, error_message: str = 'Cannot divide by zero!'):
        self.error_message = error_message

    @property
    def exception_handlers(self):
        return {
            ZeroDivisionError: lambda e: self.error_message
        }

    @ProcessException(exception_handlers)
    def divide(self, a, b):
        return a // b

@ProcessException({ZeroDivisionError: lambda e: 'Cannot divide by zero!'})
def divide(a, b):
    return a // b

assert Math().divide(4, 2) == 2
assert divide(4, 2) == 2
assert Math().divide(4, 0) == 'Cannot divide by zero!'
assert divide(4, 0) == 'Cannot divide by zero!'
assert Math().divide.__name__ == 'divide'

В принципе всю эту магию можно было и в во врапер запихнуть.

Здесь явно не то что вы хотите:


custom_handlers = custom_handlers.__get__(self, self.__class__)

Нужно использовать дескрипторы чтобы получить правильный self

При чем тут фичи баз данных, если как орм алхимия более гибкая и функциональная?

Как в SQLAlchemy сделать:


  1. аналог менеджеров (удобно иметь Model.objects для не удаленных записей и Model.all_objects для всех. Либо добавить функцию Model.objects.filtrate_for_user которая фильтрирует данные доступные для пользователя)
  2. сделать авто join (что бы, например, сделать queryset.filter(some__nested__field=2) на основе queryparams)
  3. селектнуть только некоторые поля и затем обратится к свойству объекта (User.objects.field('birthday').get().age где age это property класа User)
  4. автоматически сделать запрос только в случаи необходимости:

user = User(
    id=jwt_token_payload['user_id'], 
    username=jwt_token_payload['username']
)
print(user.id)

if some_case:
    print(user.first_name) # дополнительный запрос

А в Django ORM невозможно сделать select ... from <subquery> что очень полезно в сложных агрегациях


Почему я должен Django REST Framework делать на SQLAlchemy?

Это просто пример в каких случиях Django ORM более удобна
Я также начал с SQLAlchemy и плохо относился к Django ORM до того как поработал с Django REST Framework.


А минус в карму за то, что кто-то со мной просто не согласен?

У меня нету таких прав.

1.
def shorten_link(self, *args, **kwargs)
Как знать что принимает и возращает эта функция?
Перечитать её код? А если там еще 5 таких же "гибких" функций? Перечитать рекурсивно все n тисяч строчек кода?


2.
return response.json()['url']
Почему вы думаете что любой сервис с settings.SHORTER_URL имеет ключ url?
Что вы будете делать, если будет два сервиса с разными названиеми свойств?

Питонячий подход, ага…
Wildcard imports (from import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.
www.python.org/dev/peps/pep-0008
Django ORM не дотягивает до SQLAlchemy ровно также, как SQLAlchemy не дотягивает к Django ORM.

SQLAlchemy — поддержывает максимум фич базы даных
Django ORM — максимально удобно поддежрывает основые фичы баз даных

Посмотрите на Django REST Framework. Не думаю, что его реально сделать на SQLAlchemy

У нас на проекте использовали обе ORM через aldjemy
Но если сервер получил запрос и, исходя из бизнес-логики, решил что он ошибочный (например: объект не найден), то в таком случае я считаю правильно ответить кодом 200

Почему тогда не 400 (или 404 если ID объекта это часть урлы)?

Можете объяснить что будет если удалять и создавать тот же елемент в новом словаре?


Я так понял что размер должен постоянно расти, но думаю, что вряд ли это так:


indices =  [None, 1, None, None, None, 0, None, 2]
entries =  [[-9092791511155847987, 'timmy', 'red'],
                [-8522787127447073495, 'barry', 'green'],
                [-6480567542315338377, 'guido', 'blue']]

del the_dict['timmy']

indices =  [None, 1, None, None, None, None, None, 2]
entries =  [DKIX_DUMMY,
                [-8522787127447073495, 'barry', 'green'],
                [-6480567542315338377, 'guido', 'blue']]

the_dict['timmy'] = 'red'

indices =  [None, 1, None, None, None, 3, None, 2]
entries =  [DKIX_DUMMY,
                [-8522787127447073495, 'barry', 'green'],
                [-6480567542315338377, 'guido', 'blue'],
                [-9092791511155847987, 'timmy', 'red']]
Если идти по одному километру то получається 533 банана.
Неполная встроенная поддержка комплексных чисел: как (-1)**(0.5), так и pow(-1, 0.5) выдают ошибку вместо возврата 0+1j.

>>> (-1)**(0.5)
(6.123233995736766e-17+1j)
>>> pow(-1, 0.5)
(6.123233995736766e-17+1j)
У Lenovo есть аналого — YOGA 900 (и более старые модели)
На сколько я понимаю вы хотели делать все IDE на Kotlin. CLion написан на Kotlin, или таки C++?
>>Думаете банальная обработка антикорозийкой увеличит стоимость в два раза?
Не в два разы, но на n% дороже чем у конкурента.
У меня такая же проблема, но я держал её во влажном месте.
Думаю проблема в том, что она рассчитана на сухое место (напр. кухня), как и современные автомобили требующие хорошою дорогу.

ИМХО есть и качественные товары, но они дороги. Например немецкие товары потому и есть более качественны, потому что стоят в основном в несколько раз дороже.
Пример:
USB кабель в магазинах Германии от 10€, у нас от 1€.

Фирмы это «организмы» которые хотят получить наибольшую прибыль. Если люди «обучают» нейронную сеть их делать дешёвые товары, то кто виноват?
Скажите чесно, какую стиральную машинку вы бы купили:
с кучей функций и за Х денег или с меньшем количеством функций за 2*Х денег?

Вот вам и ответ на вопрос качества.
Да нет. Я согласен что такое поведение гугла недопустимо. Но думаю что он с таким же успехом держал бы единую копию на HDD и все равно все потерял.
Ну с таким же успехом у него мог и HDD полететь за 14 лет.
Угадайте из контекста.
У нас в городе в новостройка (как говорит реклама) есть зарядка в подземном паркинге.
>> что капитализм сам по себе — путь в никуда.
Альтернатива?
Либо я что-то не понимаю, либо кто-то врёт. Товары с alixexpress приходили без проблем и без наценки.

Information

Rating
Does not participate
Location
Львовская обл., Украина
Date of birth
Registered
Activity