company_banner

Подборка @pythonetc, ноябрь 2019


    Новая подборка советов про Python и программирование из моего авторского канала @pythonetc.

    Previous publications



    PATH — это переменная окружения, в которой хранятся пути, по которым ищутся исполняемые файлы. Когда вы просите оболочку выполнить ls, она сначала ищет исполняемый файл ls по всем путям, указанным в PATH.

    $ echo $PATH
    /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/v.pushtaev/.local/bin:/home/v.pushtaev/bin
    $ which ls
    /usr/bin/ls

    В этом примере пути в PATH разделены с помощью :. Путаница не возникнет: если путь содержит :, то он не может использоваться в PATH.

    Но это верно не для всех операционных систем. В Python вы можете узнать правильный разделитель для вашей ОС с помощью os.pathsep:

    Python 3.5.0 [...] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os
    >>> os.pathsep
    ';'

    Не путайте os.pathsep с os.path.sep, которая является разделителем для путей к файлам:

    >>> os.path.sep
    '/'



    Чтобы регулярные выражения легче было читать, можете использовать флаг re.VERBOSE. Он позволяет использовать дополнительные пробелы везде, где хотите, а также добавлять комментарии после символа #:

    import re
    
    URL_RE = re.compile(r'''
        ^
        (https?)://
        (www[.])?
        (
        (?: [^.]+[.] )+
        (   [^/]+    )  # TLD
        )
        (/.*)
        $
    ''', re.VERBOSE)
    
    m = URL_RE.match('https://www.pythonetc.com/about/')
    schema, www, domain, tld, path = m.groups()
    
    has_www: bool = bool(www)
    
    print(f'schema={schema}, has_www={has_www}')
    print(f'domain={domain}, tld={tld}')
    print(f'path={path}')
    

    re.X является псевдонимом для re.VERBOSE.



    complex — это встроенный в Python тип для комплексных чисел:

    >>> complex(1, 2).real
    1.0
    >>> abs(complex(3, 4))
    5.0
    >>> complex(1, 2) == complex(1, -2).conjugate()
    True
    >>> str(complex(2, -3))
    '(2-3j)'

    Однако не обязательно использовать его напрямую, потому что в Python есть литералы для комплексных чисел:

    >>> (3 + 4j).imag
    4.0
    >>> not (3 + 4j)
    False
    >>> (-3 - 4j) + (2 - 2j)
    (-1-6j)



    Нотацию a : b : c можно использовать для определения slice(a, b, c) с помощью одних лишь скобок:

    >>> [1, 2, 3, 4, 5][0:4:2]
    [1, 3]
    >>> [1, 2, 3, 4, 5][slice(0, 4, 2)]
    [1, 3]

    Если вы хотите передать функции slice-объект в качестве аргумента, то придётся определить его явным образом:

    def multislice(slc, *iterables):
        return [i[slc] for i in iterables]
    
    
    print(multislice(
        slice(2, 6, 2),
        [1, 2, 3, 4, 5, 6, 7],
        [2, 4, 2, 4, 2, 4, 2],
    ))

    Вот так можно преобразовать подобную функцию в объект, который поддерживает [a : b : c]:

    from functools import partial
    
    
    class SliceArgDecorator:
        def __init__(self, f):
            self._f = f
    
        def __getitem__(self, slc):
            return partial(self._f, slc)
    
    slice_arg = SliceArgDecorator
    
    
    @slice_arg
    def multislice(slc, *iterables):
        return [i[slc] for i in iterables]
    
    
    print(multislice[2:6:2](
        [1, 2, 3, 4, 5, 6, 7],
        [2, 4, 2, 4, 2, 4, 2],
    ))



    __getattribute__ — это мощный инструмент, позволяющий легко использовать паттерн делегирования, когда это уместно. Так можно добавить возможность сравнения с несравниваемым объектом:

    class CustomEq:
        def __init__(self, orig, *, key):
            self._orig = orig
            self._key = key
    
        def __lt__(self, other):
            return self._key(self) < self._key(other)
    
        def __getattribute__(self, name):
            if name in {'_key', '_orig', '__lt__'}:
                return super().__getattribute__(name)
    
            return getattr(self._orig, name)
    
    class User:
        def __init__(self, user_id):
            self._user_id = user_id
    
        def get_user_id(self):
            return self._user_id
    
    
    def comparable(obj, *, key):
        return CustomEq(obj, key=key)
    
    
    user1 = comparable(User(1), key=lambda u: u.get_user_id())
    user2 = comparable(User(2), key=lambda u: u.get_user_id())
    
    print(user2 > user1)  # True
    print(user2 < user1)  # False
    print(user2.get_user_id())  # 2
    
    Mail.ru Group
    877,55
    Строим Интернет
    Поделиться публикацией

    Похожие публикации

    Комментарии 0

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

    Самое читаемое