Рубрики
Без рубрики

Змеиные глаза: область и яф

Где мы крадем хорошие концепции из других языков, чтобы создать сомнительный код Python. Tagged с Python, ошибочным, смешным.

Змеиные глаза (серия 2 частей)

Один из моих домашних питомцев берет концепции с других языков и «переводит» их на Python. Не потому, что он делает хороший код, а потому, что это вызов, и это делает меня счастливым.

На этот раз я пошел после двух простых концепций – вложенных кодовых блоков и iife. Оба служат сходными целями, и оба отсутствуют на Python.

В C ++ блоки часто используются для ограничения срока службы объектов и удержать их от нашего пути, когда мы закончили с ними. В Python жизнь, как правило, меньше вызывает озабоченность (как мы заменяем raii и деструкторы с Контекст-менеджеры ), но наличие имен переменных с нашего пути желательно.

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

Python не имеет ни одной из этих конструкций. Невозможно создать вложенную блокировку кода в Python (добавление другого уровня отступления могло бы просто жаловаться на неожиданные), и, хотя Lambdas существуют, они допускают только одно выражение, что делает их в основном неактуальными для IIFE. С другой стороны, Python предлагает нам две замечательные конструкции, которые можно использовать практически везде – классы и функции.

Классы и вложенные блоки 🧱🧱🧱

В Python как классы, так и функции могут быть вложены. Вы можете определить класс внутри класса, функцию в функции, класс в функции или функцию в классе. Все то же самое. Более того-вы можете иметь контроль потока как в функции (ну, очевидно,) и классовых тела (мета-спрограммирование много?). Кроме того, как вложенные функции, так и вложенные классы создают новые переменные прицелы, сохраняя свои внутренности внутри, а также являются закрытыми, способными захватить значения из их приоритетных областей. Таким образом, они являются идеальными инструментами для наших махинаций, изгибающихся на языке.

Во -первых, вложенные кодовые блоки. Я предлагаю вам следующее решение:

def f(x):
    print('Classes are great for creating blocks.')
    class _:
        y = x * 2
        print(f'y = {y}')

    print('y is not defined here.')
    y

f(21)

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

Тем не менее – есть некоторые предостережения. Во -первых, класс остается в масштабах, как и все переменные, определенные в нем. Они не могут быть собраны мусором, пока функция не завершится. Вы можете проверить это самостоятельно, пытаясь получить доступ к _.y. В приведенном выше примере. Чтобы исправить это, нам нужно избавиться от класса или, по крайней мере, его содержимого. Есть много способов достичь этого:

# Replace the class with a bool
@bool
class _:
    x = 1
    print(x)


# Replace the class with None
def empty(*args): return None


@empty
class _:
    x = 1
    print(x)


# Use a metaclass to delete all the variables inside the class
class BlockMeta(type):
    def __new__(cls, name, bases, dict_):
        return super().__new__(cls, name, bases, {})


class Block(metaclass=BlockMeta):
    pass


class _(Block):
    x = 1
    print(x)

Я лично разорван между мета-классом, так как он явный и ясный, и @bool Подход, как это требуется для дополнительного шаблона.

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

Функции и iife 🐍🐍🐍

С решением для вложенных блоков в руке, пришло время получить надлежащий iife в Python. Для этого мы, естественно, будем использовать функцию. Наряду с ними, мы будем использовать лучшего друга функции – декоратор!

def iife(f):
    return f()

def describe_number(n):
    @iife
    def message():
        if n < 0:
            return f'{n} is smaller than 0'
        elif n > 0:
            return f'{n} is larger than 0'
        return f'{n} is 0'

    print(message)

describe_number(-1)
describe_number(0)
describe_number(1)

Используя декоратор, мы сразу же называем функцию, привязывая имя функции к возвращаемому значению вместо самой функции. Функция, возвращающая Нет (или без оператора возврата) просто свяжет имя с Нет Анкет

Хотя это выглядит немного более грязно, это также может удвоиться в качестве решения для вложенных блоков. И в отличие от классового решения – оно может быть свободно вложено.

def iife(f):
    return f()


def block(f):
    f()


def f(x):
    print('Functions are great for creating blocks.')

    @block
    def _():
        my_x = x + 1
        @iife
        def y():
            return my_x * 2

        @block
        def _():
            print(f'y = {y}')

    print('y is not defined here.')
    y


f(20)

Вот и все на сегодня. Надеюсь, вам было повеселиться.

Змеиные глаза (серия 2 частей)

Оригинал: “https://dev.to/tmr232/snake-eyes-scopes-and-iife-50h2”