Ответы пользователя по тегу Python
  • Как сортировать разные телефонные номера?

    Не могу подсказать никакой библиотеки для работы с числительными на русском (да и на любом другом языке), но вы не думали сделать парсер попроще?
    Что-нибудь вроде:
    import re
    
    
    REPLACEMENT = {
    	'ноль': '0',
    	'один': '1',
    	'два': '2',
    	'три': '3',
    	'четыре': '4',
    	'пять': '5',
    	'шесть': '6',
    	'семь': '7',
    	'восемь': '8',
    	'девять': '9'
    }
    
    
    PHONE_REGEX = re.compile('(\+)?\d{10,11}')
    
    
    def parse_phones(file_path):
    	parsed = []
    	unparsed = []
    	with open(file_path, 'r') as file:
    		for line in file:
    			name, phone, *_ = line.split(':')
    			name = name.strip()
    			phone = phone.strip()
    			for key, value in REPLACEMENT.items():
    				phone = phone.replace(key, value)
    			if PHONE_REGEX.match(phone):
    				phone_len = len(phone)
    				if phone_len == 10:
    					phone = '+7' + phone
    				elif phone_len == 11:
    					phone = '+7' + phone[1:]
    				parsed.append((name, phone))
    			else:
    				unparsed.append(line)
    	return parsed, unparsed

    Вместо засовывания в списки можно сразу писать в файлы. Как минимум, это уменьшит количество "неизвестных" номеров.
    Ответ написан
    1 комментарий
  • Как узнать переменные при ошибке в коде?

    Попробуйте вот такое решение. Код для Python 3. Основано на setprofile, так что может вам не подойти, если ваш код многопоточный.
    import sys
    import logging
    
    
    LOG = logging.getLogger(__name__)
    
    
    def handle_exception_with_locals(func):
        def wrapped(*args, **kwargs):
            locals = {}
            def tracer(frame, event, arg):
                """ Эта функция будет инспектировать код,
                    который будет выполнятся после того, 
                    как она будет установлена профайлером.
                    Профайлер срабатывает только на события
                    retrun и call (при этом exception интерпретируется как return)
                """
                nonlocal locals
                if event == 'return':
                    locals = frame.f_locals.copy()
            sys.setprofile(tracer)
            try:
                res = func(*args, **kwargs)
            except Exception as e:
                log_pattern = ('{}(*{}, **{}) failed with {}. ' + 
                               'Local function variables: {}; ' +
                               'Global variables: {};')
                LOG.error(log_pattern.format(
                    func.__name__, repr(args), repr(kwargs),
                    repr(e), repr(locals), repr(globals()))
                )
                raise
            finally:
                sys.setprofile(None)
            return res
        return wrapped
    
    
    @handle_exception_with_locals
    def test(a, b):
        a = 16
        b = 7
        c = 9
        raise ValueError('Oops!')
    
    
    test(1, 2)
    Ответ написан
    Комментировать
  • SQlAlchemy. Как оптимизировать запросы?

    Посоветую вам начать с включения SQLALCHEMY_ECHO и просмотра плана результирующего запроса.
    Как быстрый совет - ограничивайте запрос данными, которые вам нужны, и не бойтесь подзапросов. В большей части случаев бэкенд БД сделает всю оптимизацию за вас.
    result = Context.query.join(
        Request, Request.context_id == Context.id_
    ).join(
        Point, Point.request_id == Request.id_
    ).group_by(Context.id_).with_entities(
        Context.field1, ...
        func.count(Point.id_).label('points_count')
    )
    Ответ написан
    8 комментариев
  • Как лучше всего обрабатывать ошибки в python?

    Советую вам посмотреть в сторону декораторов. Полезно будет как для решения задачи, так и для общего ознакомления с синтаксическими возможностями языка.
    Дам пример самого простого декоратора, единственная функция которого "тихо" логгировать любой exception:
    import logging
    
    
    LOG = logging.getLogger(__name__)
    
    
    def handle_silently(function):
        def wrapped(*args, **kwargs): 
            result = None
            try:
                result = function(*args, **kwargs)
            except Exception as e:
                LOG.error(
                    '{}(*{}, **{}) failed with exception {}'.format(
                        function.__name__, repr(args), repr(kwargs), repr(e) 
                     )
                )
            return result
        return wrapped
    
    
    @handle_silently
    def some_function(test):
        return test / 0

    Конструкция @handle_silently заменит вашу функцию some_function на функцию wrapped.
    Механика работы wrapped является, скорее, антипаттерном, поскольку замалчивать exception совсем и тем более отдавать вместо него None - это гарантированный способ выстрелить себе в ногу. Это просто пример, в боевом проекте я бы посоветовал ререйзить (LOG.error(...); raise) ошибку в декораторе и обрабатывать несредственно в месте вызова функции (логгирование, естественно, можно и оставить).
    Для затравки и для демонстрации того, как это может быть полезно - декотораторы могут быть параметрическими (достигается это путём создания фабрики декораторов):
    def decorators_fabric(handler_function):
        def decorator(function):
            def wrapped(*args, **kwargs):
                handler_function(function.__name__, repr(args), repr(kwargs))
                return function(*args, **kwargs)
            return wrapped
        return decorator
    
    
    @decorators_fabric(print)
    def my_test_function(arg1, arg2):
        return arg1 * arg2
    Ответ написан
    Комментировать
  • Почему replace не работает?

    \xa0 это неразрывный пробел. в replace используется обычный (\x20).
    Решение уже подсказали.
    Можно повозиться с регулярными выражениями (для общего ознакомления с различными видами извращений):
    import re
    replacement = ''
    string_to_replace = '\xa0  test  data       '
    strip_re = re.compile(r'(^\s+)|(\s+$)')
    result = strip_re.sub(replacement , string_to_replace)
    Ответ написан
    Комментировать
  • Как получить доступ к области видимости?

    import sys
    
    
    def a():
    	j = 10
    	h = 20
    	b()
    
    
    def b():
    	callingframe = sys._getframe(1)
    	print(callingframe.f_locals)
    
    a()
    Ответ написан
    Комментировать