15.11.2024

Лучше не стоит: разбираемся в связях между объектами, функциями, генераторами и сопрограммами / Хабр

разбираемся в связях между объектами, функциями, генераторами и сопрограммами / Хабр

Пару слов о статье.

Она не первой свежести – 2015 год. Вероятно, её уже кто-то перевёл до меня. Тем не менее, я не нашёл такого перевода (в том числе на Хабре — искал по имени автора, а как ещё искать переводы?).

Автор легко и со вкусом рассказывает об особенностях Python как языка программирования, в котором всё является объектом как таковым. В переводе, я постарался придерживаться стиля оригинала, в том числе, и речи от первого лица.

Итак, поехали.

Давайте проведём исследование некоторых взаимосвязей функций, объектов, генераторов и корутин в Python. На уровне теории, каждая из этих концепций очень сильно отличается от других; но динамическая природа языка позволяет им заменять друг друга на практике. Предупреждаю: мы рассмотрим рабочие, но очень странные примеры кода; я не советую вам применять их в реальных проектах!

Функции

Функция – это объект, который может быть выполнен. При этом, она вызывается из одного места в коде, и может принимать другие объекты в качестве параметров (а может и вовсе обходиться без них). Функция существует только в одном месте и всегда возвращает лишь один объект.

Здесь, мы уже видим некоторые сложности; возможно, вы уже задались некоторыми из следующих вопросов:

  • А если в теле функции несколько ключевых слов return? (Да, но только одно из них приведёт к остановке работы функции в каждом единичном случае выполнения кода)

  • Что, если функция вообще ничего не возвращает? (В этом случае, она всё-таки возвращает кое-что: специальный объект None)

  • Разве мы не можем возвращать несколько объектов через запятую? (Можем, но все эти объекты, в сумме, являют собой кортеж – он и будет считаться возвращаемым объектом)

Взгляните на функцию:

def average(sequence):

    avg = sum(sequence) / len(sequence)

    return avg

print(average([3, 5, 8, 7]))

(вывод в консоль: 5. 75)

Ничего необычного. Вероятно, вы уже знаете, что представляют из себя объекты и классы в Python. Я определяю объект как конкретные данные, у которых есть своё, особое, поведение. Класс – шаблон для объекта, где данные обычно представлены набором атрибутов, а поведение реализовано набором методов (тех же функций).

Но это не обязательно должно быть так 😉

Код обычного объекта:

class Statistics:

    def __init__(self, sequence):

        self.sequence = sequence

    def calculate_average(self):

        return sum(self.sequence) / len(self.sequence)

    def calculate_median(self):

        length = len(self.sequence)

        is_middle = int(not length % 2)

        return (

            self.sequence[length // 2 - is_middle] +

            self.sequence[-length // 2]) / 2

statistics = Statistics([5, 2, 3])

print(statistics. calculate_average())

(вывод в консоль: 3.3333333…)

Последовательность (sequence), переданная в такой класс при создании – это единственные данные, которыми оперирует объект. После инициализатора __init__ записаны два метода.

Но только один из них был использован в этом конкретном примере; и как сказал Джек Дидерих (Jack Diederich) в своей известной речи Stop Writing Classes,

Класс с единственным методом после инициализатора должен быть реализован как простая функция

Поэтому, я включил в пример кода второй метод, чтобы вывод о необходимости реализации в виде класса показался вам правдоподобным. (Хотя это не так; здесь вам поможет модуль statistics в Python 3.4+. Никогда не пишите того, что уже до вас было написано, отлажено и протестировано).

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

Например: вы знали, что функция – это тоже объект? По факту, всё, с чем вы можете взаимодействовать в Python, определяется в исходном коде для интерпретатора CPython как структура «PyObject».

Это значит, что мы можем задать атрибутом для функции любой объект. Даже функцию. Пример ниже не рекомендуется для выполнения в домашних условиях (а на работе – тем более):

Издеваемся над функциями

def statistics(sequence):

    statistics.sequence = sequence

    return statistics

def calculate_average():

    return sum(statistics.sequence) / len(statistics.sequence)

statistics.calculate_average = calculate_average

print(statistics([1, 5, 8, 4]).calculate_average())

(вывод в консоль: 4.5)

Это довольно безумный пример (хотя мы только начали). Сама функция statistics объявляется как объект с двумя атрибутами: лист sequence и calculate_average как другой объект-функция. Для забавы, функция возвращает саму себя, поэтому, мы можем вызывать calculate_average в одной строке с print.

Имейте в виду, что statistics – это объект, а не класс. Мы не старались скопировать класс как паттерн из предыдущего примера; скорее, текущий пример похож на экземпляр класса.

Сложно представить какой-либо повод писать такой код в реальных проектах. Возможно – для реализации (анти-)паттерна Singleton, который популярен в некоторых других ЯП. Поскольку может существовать только одна функция statistics, то невозможно реализовать два разных экземпляра этой функции, с двумя разными атрибутами sequence, в отличие от того, как это легко делается с классом.

Но мы можем более точно симулировать структуру класса (как паттерна), используя функцию как конструктор:

Почти класс

def Statistics(sequence):

    def self():

        return self. average()

    self.sequence = sequence

    def average():

        return sum(self.sequence) / len(self.sequence)

    self.average = average

    return self

statistics = Statistics([2, 1, 1])

print(Statistics([1, 4, 6, 2]).average())

print(statistics())

(вывод в консоль: 3.25 и 1.333333333…)

Очень смахивает на Javascript, не так ли? Функция Statistics ведёт себя как конструктор, который возвращает объект (в нашем случае – функция self). Этот возвращаемый объект-функция, в свою очередь, имеет несколько связанных с нею атрибутов – так что у нас есть объект с данными и неким поведением. В последних трёх строках мы можем создать два отдельных «экземпляра» Statistics, прямо так, как будто мы использовали класс. Наконец, раз Statistics это функция – мы можем напрямую вызвать её. Такой вызов передаётся функции average (или это уже считается методом? Я не берусь ручаться).

Прежде, чем мы продолжим, обратите внимание, что такая симуляция функционала классов вовсе не означает, что в результате мы получаем точно такое же поведение этой структуры вне интерпретатора Python. Все функции – это объекты; но не всякий объект – это функция. Базовая реализация их различна, и если использовать такой код в реальном проекте, это быстро приведёт к разного рода казусам. В обычном коде, вариант привязки атрибутов к функциям редко бывает полезен. Я встречал такие реализации для интересных вариантов диагностики и тестирования, но в основе своей это лишь трюки забавы ради.

Однако понимание, что функция — это объект, позволяет нам передавать их для вызова.

Рассмотрим основу частичной реализации паттерна наблюдателя (observer):

class Observers(list):

    register_observer = list.append

    def notify(self):

        for observer in self:

            observer()

observers = Observers()

def observer_one():

    print('Первый был вызван')

def observer_two():

    print('Второй был вызван')

observers. register_observer(observer_one)

observers.register_observer(observer_two)

observers.notify()

(вывод в консоль: ‘Первый был вызван’ ‘Второй был вызван’)

На второй строке, я специально сделал код менее понятным, чтобы подтвердить свой изначальный тезис «большинство примеров в этой статье – смешные». Здесь, я создаю новый атрибут класса register_observer, который хранит ссылку на функцию list.append. Так как текущий класс наследуется от базового класса списков (list), всё, что делает вторая строка – создаёт ссылку на метод, которая могла бы выглядеть так:

def register_observer(self, item):

    self.append(item)

И именно код выше – правильный способ реализации такого функционала, иначе никто не поймёт, какая логика заложена в вашем коде. А вот 2 и 3 строки (в спойлере — с конца) вы, возможно, захотите использовать на практике. Здесь две callback-функции передаются в регистрирующую функцию, и это распространённая практика. Не будь функции объектами, пришлось бы создавать группу классов с одним простецким методом внутри, названным, например, execute, и уже их и передавать.

Но что-то мы слишком стали серьёзны. Давайте сделаем нечто действительно глупое, например, функцию, которая возвращает объект функции:

Тут глупость

silly():

    print("глупость")

    return silly

silly()()()()()()

(вывод в консоль: шестикратная «глупость» + адрес объекта в памяти)

Я не использую такую фичу слишком часто, но иногда это бывает полезно.

Например: если вы пишете функцию и вызываете её из множества мест в коде, а позднее обнаруживается, что ей необходимо сохранять какое-то состояние. Для этого, лучше заменить функцию объектом с реализованным магическим (dunder) методом __call__() без изменения всех мест вызова.

Или, если у вас есть callback-реализация, которая обычно передаётся функции, вы можете использовать вызываемый объект, когда необходимо сохранить более сложное состояние.

Также, я видел декораторы, сделанные из объектов, и они сохраняли дополнительное состояние или поведение.

Генераторы

Поговорим о генераторах. Разумеется, реализовать их мы собираемся самым топорным образом. Мы можем взять за основу идею, в которой функция возвращает объект, для создания элементарного генератора-объекта, который вычисляет последовательность Фибоначчи:

Фибоначчи

def FibFunction():

    a = b = 1

    def next():

        nonlocal a, b

        a, b = b, a + b

        return b

    return next

fib = FibFunction()

for i in range(8):

    print(fib(), end=' ')

(вывод в консоль: 2 3 5 8 13 21 34 55)

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

Мы могли бы реализовать такой же функционал через класс:

class FibClass():

    def __init__(self):

        self.a = self.b = 1

    def __call__(self):

        self.a, self.b = self.b, self.a + self.b

        return self.b

fib = FibClass()

for i in range(8):

    print(fib(), end=' ')

Ни один из этих примеров не подчиняется протоколу итератора. И как бы я ни бился, FibFunction не удастся заставить работать в связке со встроенным функционалом языка – next(). Даже после просмотра исходного кода CPython в течение нескольких часов.

Как я упоминал ранее, использование синтаксиса функций для построения псевдо-объектов быстро приводит к разочарованию.

А вот основанный на FibClass объект можно легко настроить для выполнения протокола итератора:

class FibIterator():

    def __init__(self):

        self.a = self.b = 1

    def __next__(self):

        self.a, self.b = self.b, self.a + self.b

        return self.b

    def __iter__(self):

        return self

fib = FibIterator()

for i in range(8):

    print(next(fib), end=' ')

Это, кстати, стандартная реализация итератора, как есть. Но выглядит как-то некрасиво и многословно. К счастью, мы можем получить тот же эффект при помощи функции, которая включает оператор yield:

Елдим!

def FibGenerator():

    a = b = 1

    while True:

        a, b = b, a + b

        yield b

fib = FibGenerator()

for i in range(8):

    print(next(fib), end=' ')

print('n', fib)

Версии с генератором уже более читабельны, чем две первые. Здесь следует держать в голове то, что генератор не является функцией – объект FibGenerator возвращает объект (как иллюстрация фразы “generator object” в консольном выводе).

В отличие от обычной функции, генераторная не выполняет никакого кода, когда мы её вызываем. Вместо этого, она собирает объект-генератор и возвращает его. Вы можете думать об этом как о неявном декораторе: интерпретатор видит ключевое слово yield и заключает его в декоратор, который возвращает объект. А вот чтобы код внутри функции начал выполняться, мы должны использовать функцию next() – либо явно, либо через цикл for или же yield from.

Генератор, конечно, является объектом. Но намного удобнее думать о создающей его функции как об обычной: которая может передавать данные в одно место и возвращать значения несколько раз. Это что-то вроде универсальной функции: очень легко реализовать генератор, который ведёт себя не совсем как функция, и возвращает лишь одно значение:

Реализация странного генератора

def average(sequence):

    yield sum(sequence) / len(sequence)

print(next(average([1, 2, 3])))

(вывод в консоль: 2. 0)

К сожалению, момент вызова функции не так легко воспринимается, так как в связке с yield мы обязаны вставить этот надоедливый next(). Очевидный способ обхода этого ограничения – добавить __call__() к генератору, но это не удастся, если мы попытаемся использовать присвоение атрибутов или наследование. Существуют оптимизации, которые позволяют генераторам работать в коде С быстрее, а также не позволяют нам назначать атрибуты. Однако, мы можем обернуть генератор в объект, похожий на функцию, используя нелепый декоратор:

Усложняем генератор!

def gen_func(func):

    def wrapper(*args, **kwargs):

        gen = func(*args, **kwargs)

        return next(gen)

    return wrapper

@gen_func

def average(sequence):

    yield sum(sequence) / len(sequence)

print(average([1, 6, 3, 4]))

Делать так – полный бред. Я имею в виду, просто напишите обычную функцию, ради всего святого!

Хотя, возникает соблазн создать кое-что поинтереснее:

И ещё усложняем!

def callable_gen(func):

    class CallableGen:

        def __init__(self, *args, **kwargs):

            self.gen = func(*args, **kwargs)

        def __next__(self):

            return self.gen.__next__()

        def __iter__(self):

            return self

        def __call__(self):

            return next(self)

    return CallableGen

@callable_gen

def FibGenerator():

        a = b = 1

        while True:

            a, b = b, a + b

            yield b

fib = FibGenerator()

for i in range(8):

    print(fib(), end=' ')

(вывод в консоль: 2 3 5 8 13 21 34 55)

Чтобы полностью обернуть генератор в декоратор, нам необходимо предоставить ему доступ к некоторым другим методам – send, close и throw. Такой декоратор можно использовать для вызова генератора любое количество раз, обходясь без next(). У меня был соблазн сделать это, чтобы мой код выглядел чище, если в нём много вызовов этой функции… Но я советую от такого воздерживаться. Программисты (включая вас), которые будут читать ваш код, сойдут с ума, пытаясь понять, что же делает этот «вызов функции». Лучше всего – просто привыкнуть к функционалу next()

Корутины

Итак, мы провели некоторые параллели между генераторами, объектами и функциями. Теперь, поговорим об одной из самых запутанных концепций в Python – корутинах (coroutines, или «сопрограммы»). Обычно, их определение звучит, как «генераторы, в которые можно отправлять значения». На уровне реализации это, видимо, самое разумное определение. Однако, в теоретическом аспекте, более точно определить корутины можно как конструкции, которые могут как принимать, так и возвращать значения – и то, и другое возможно в одном или нескольких местах программы.

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

Это общий случай. А генераторы и функции – это специальные случаи корутин, просто они ограничены в том, где они могут принимать и возвращать значения.

Вот пример корутины:

def LineInserter(lines):

    out = []

    for line in lines:

        to_append = yield line

        out.append(line)

        if to_append is not None:

            out.append(to_append)

    return out

emily = """I died for beauty, but was scarce

Adjusted in the tomb,

When one who died for truth was lain

In an adjoining room.

He questioned softly why I failed?

“For beauty,” I replied.

“And I for truth,—the two are one;

We brethren are,” he said.

And so, as kinsmen met a night,

We talked between the rooms,

Until the moss had reached our lips,

And covered up our names.

"""

inserter = LineInserter(iter(emily.splitlines()))

count = 1

try:

    line = next(inserter)

    while True:

        line = next(inserter) if count % 4 else inserter.send('-------')

        count += 1

except StopIteration as ex:

    print('\n' + '\n'.join(ex.value))

(вывод в консоль: текст, разделённый ‘——-‘ через каждые 4 строки)

Объект LineInserter зовётся корутиной потому, что, в отличие от генератора, ключевое слово yield находится справа от оператора присваивания. Только и всего. Теперь, когда yield возвращает строку, объект сохраняет это значение, чтобы иметь возможность отправить его обратно в сопрограмму, прямиком в to_append.

Мы можем отправить значение обратно при помощи inserter.send в исполняющем коде (он находится под текстом поэмы, в спойлере). Если вместо этого использовать next(), то в to_append придёт None. И не спрашивайте меня, почему next – это функция, а send – метод, если они оба делают почти одно и то же!

Итак, вызов send успешно разделяет поэму Эмили Дикинсон (Emily Dickinson) на блоки из 4 строк в консольном выводе. Таким образом, сопрограммы могут предоставить дополнительный функционал, когда обычная «односторонняя» (one way) итерация не совсем подходит.

Код корутины мне очень нравится, но исполняющий её код можно улучшить. Недавно, я эмулировал функционал мененджера контекста contextlib.suppress для замены пункта except на callback-функционал:

Делаем замену в блоке try-except

def LineInserter(lines):

    out = []

    for line in lines:

        to_append = yield line

        out. append(line)

        if to_append is not None:

            out.append(to_append)

    return out

from contextlib import contextmanager

@contextmanager

def generator_stop(callback):

    try:

        yield

    except StopIteration as ex:

        callback(ex.value)

def lines_complete(all_lines):

    print('\n' + '\n'.join(all_lines))

emily = """ ТОТ ЖЕ ТЕКСТ ПОЭМЫ """

inserter = LineInserter(iter(emily.splitlines()))

count = 1

with generator_stop(lines_complete):

    line = next(inserter)

    while True:

        line = next(inserter) if count % 4 else inserter.send('-------')

        count += 1

Теперь отловом лишнего занимается generator_stop, и такой менеджер контекста можно использовать в самых разных ситуациях, когда необходимо обработать StopIteration.

Поскольку корутины и генераторы – практически одно и то же, они оба могли бы эмулировать работу функции. Мы даже можем вызвать одну и ту же корутину несколько раз, как если бы она была функцией:

Делаем корутину вызываемой:

def IncrementBy(increment):

    sequence = yield

    while True:

        sequence = yield [i + increment for i in sequence]

sequence = [10, 20, 30]

increment_by_5 = IncrementBy(5)

increment_by_8 = IncrementBy(8)

next(increment_by_5)

next(increment_by_8)

print(increment_by_5.send(sequence))

print(increment_by_8.send(sequence))

print(increment_by_5.send(sequence))

(вывод в консоль: [15, 25, 35] при каждом вызове increment_by)

Обратите внимание на два вызова next(). Они эффективно «подготавливают» генератор, продвигая его к первому yield. Тогда каждый вызов send выглядит, по факту, как одиночный вызов функции. Исполняющий программу код не совсем похож на вызов функции, но секунду, сейчас мы применим чёрную магию декораторов:

Щепотка чёрной магии

def evil_coroutine(func):

    def wrapper(*args, **kwargs):

        gen = func(*args, **kwargs)

        next(gen)

        def gen_caller(arg=None):

            return gen.send(arg)

        return gen_caller

    return wrapper

@evil_coroutine

def IncrementBy(increment):

    sequence = yield

    while True:

        sequence = yield [i + increment for i in sequence]

sequence = [10, 20, 30]

increment_by_5 = IncrementBy(5)

increment_by_8 = IncrementBy(8)

print(increment_by_5(sequence))

print(increment_by_8(sequence))

print(increment_by_5(sequence))

Декоратор принимает функцию и возвращает новую – wrapper, которая назначается переменной IncrementBy. Теперь, каждый раз при вызове этой переменной, она собирает генератор, используя исходную функцию, и продвигает его к первому оператору yield, используя next. Он возвращает новую функцию, которая вызывает send у генератора каждый раз, когда он вызывается. Эта функция делает аргумент по умолчанию равным None, чтобы он также мог работать, если мы вызываем next вместо send.

Не смотря на очевидную читабельность исполняющего кода, я крайне не рекомендую использовать такой стиль кода, в котором корутины ведут себя как гибридные объекты \ функции. Аргумент, в котором другие программисты не смогут залезть вам в голову, остаётся в силе. Да и потом: send может принимать лишь один аргумент, и вызываемый объект весьма ограничен.

Прежде, чем мы закончим обсуждение, взглянем коротко на исполняющий код, который мог бы обработать строфу emily без использования корутин, генераторов, функций или объектов:

for index, line in enumerate(emily. splitlines(), start=1):

    print(line)

    if not index % 4:

        print('------')

Максимально просто.

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

Конечно, для сопрограмм есть случаи, когда их применение — незаменимо..

Например, моделирование системы с переходом между состояниями; или выполнение асинхронной работы с библиотекой asyncio (которая оборачивает все возможные сумасшествия с помощью StopIteration, каскадных исключений и т.д.). Или – вот такие реализации, как выше, ради баловства.

Итак, стало ясно, что в Python существует не один способ сделать множество вещей. К счастью, большинство из них не так очевидны, и обычно есть «один, и желательно только один, очевидный способ сделать что-то», цитируя Дзен Python.

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

Стоит ли брать питомца из приюта или всё-таки лучше не рисковать?

Какие мифы о приютских животных самые устойчивые, как за одну минуту понять, готов ли ты взять оттуда питомца, и о чём спросить куратора на месте, объяснила Светлана Сафонова – директор благотворительного фонда помощи животным «Дарящие надежду» и эксперт pet-friendly сообщества «Хвост Ньюс».

Светлана Сафонова – директор благотворительного фонда помощи животным «Дарящие надежду» и эксперт pet-friendly сообщества «Хвост Ньюс»

Почему люди боятся брать кошек и собак из приютов

За 12 лет работы фонда помощи животным «Дарящие надежду» мы постоянно сталкиваемся с устойчивыми мифами о кошках и собаках из приютов. Приведу самые живучие и сразу их развею.

  • Животные из приютов агрессивные и дикие, их невозможно воспитать.

На самом деле, питомцы в приютах самые разные. Многие такие же ласковые и послушные, как самые «залюбленные» домашние. У кого-то бывают особенности поведения, но при правильном подходе проблема решается легко и быстро. 

Волонтёры всех приютов социализируют своих подопечных, занимаются с ними, возят на выставки и мероприятия.

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

Питомцы в приютах обработаны от внешних и внутренних паразитов и проходят вакцинацию. Как у любого другого живого существа, у них могут быть проблемы со здоровьем, но об этом обязательно предупредит куратор.

  • В приютах только беспородные и некрасивые питомцы

Туда попадают и совершенно здоровые питомцы любых пород, которые внезапно лишились владельцев, оказались на улице или попали в другую сложную ситуацию. Многие – это бывшие домашние. Они попали в приют или на передержку из семьи, так что совершенно готовы к жизни в доме или квартире.  

В эти мифы обычно верят люди, которые никогда не бывали в приютах и не видели животных из них. Всё это мы старательно и подробно объясняем из года в год. К счастью, лед тронулся. Сейчас мы видим, что времена, когда люди категорически не хотели брать собаку или кошку из приюта, уходят в прошлое.

Сначала люди опасаются, а потом, говорят, как они счастливы

Если вы собираетесь завести питомца из приюта, но что-то вас еще все-таки удерживает, проверьте себя прямо сейчас. Задайте себе вопрос: «Зачем я хочу это сделать?» И ответьте на него честно.

Если хотите сделать ребёнку подарок, вам пока не стоит заводить питомца. Живое существо вообще не может быть подарком. Именно такие «подарки» потом оказываются никому не нужны, попадают на улицы, а далее в приют – и это ещё не самый плохой сценарий. 

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

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

Еще раз подчеркну, любую проблему можно решить. Главное, помнить, что питомец воспринимает мир как ребёнок. Доказано, что интеллект собаки приравнивается к интеллекту 3 летнего ребенка. Наказания здесь не сработают. А объяснения, любовь и забота – даже очень. 

Как выбрать приют и о чём спросить куратора

Выберете приют, удобный по местоположению. Зайдите на его сайт или страничку в соцсетях, почитайте информацию, ознакомьтесь с отзывами. Даже если с виду все идеально, обязательно созвонитесь с волонтёром из этой организации. Расспросите о правилах посещения и договоритесь о визите. Перед тем, как взять питомца, рекомендую сначала съездить в приют, пообщаться с сотрудниками, познакомиться с животными, а ещё лучше – помочь: поиграть с кошками или погулять с собаками, привезти что-то полезное из списка (он всегда есть на сайте).  

А теперь расскажу, что делать, когда визит в приют состоялся и вы выбрали питомца: 

  • Свяжитесь с куратором и подробно расспросите его о состоянии питомца. Задавайте много вопросов, не стесняйтесь! Это нормально, что вам интересно всё. 
  • Будьте готовы, что куратор будет задавать вопросы и вам. Некоторые из них могут показаться очень личными: семейное положение, жилищные условия, уровень дохода… Ничего не скрывайте! Вопросы задают не из праздного любопытства. Куратору важно понять, в чьи руки попадёт его подопечный.
  • Приготовьтесь подписать договор.
  • Оставайтесь на связи с куратором, когда уже забрали питомца. Если с первого дня что-то пошло не так, вы переживаете или вам что-то непонятно, не нужно искать ответы в интернете или у знакомых. Задавайте вопросы куратору, даже если они, на ваш взгляд, очень глупые. Лучше сразу обозначить проблему и вместе придумать, как её решить, чем потом исправлять последствия неправильного поступка.

Чтобы не разочароваться в питомце, важно с самого начала себя настраивать: собаки и кошки никогда ни в чём не виноваты. Их поведение – это последствие неправильного воспитания или недостатка внимания человека. Животные никогда не хотят специально разозлить нас или навредить – они по природе не способны строить такие планы. Если вы вовремя это поймёте, убережёте себя (и питомца) от лишнего стресса. 

1февраля 2022

1июля 2023

Мероприятие

Онлайн

Волонтерский штаб платформы ДОБРО.РФ

Стать волонтером

И ещё совет – посмотрите вокруг! Всё больше «собачников» гуляют именно с «бывшеприютскими» животными. Всё больше людей в соцсетях рассказывают, как забрали кошку из приюта или с улицы. Поговорите с ними. Пусть они поделятся с вами опытом. Посмотрите на их счастливых питомцев. Сейчас они находятся в безопасности и любви, именно благодаря таким людям как вы. Желаю вам найти питомца своей мечты и много счастливых лет создавать с ним уют друг для друга!

Ранее Добро.Журнал рассказывал, как стать волонтёром Арктики.

Заглядывайте в наши сообщества!

ВКонтакте — vk.com/dobro.press

Телеграм — t.me/dobrojournal

Цитаты того не стоят — BrainyQuote

Есть так много людей, которые спорят или борются по вопросам, которые не имеют большого значения. Мы все должны понять, что оно того не стоит.

Калпана Чавла

Иногда легко увидеть негативную сторону вещей или задаться вопросом, почему люди запугивают вас. Вы можете подумать: «Может быть, они правы. Может быть, я того не стою. Может быть, я должен просто уйти. Но именно тогда вы должны бороться сильнее всего. Теперь я имею в виду борьбу не физически, а ментально. Продолжай быть собой.

Райни Родригес

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

Райан Гослинг

Вы можете иметь все на свете, но если вы не счастливы внутри себя, оно того не стоит.

Джиджи Великолепная

Если вы действительно не хорошо проводите время, оно того не стоит.

Кайл Чендлер

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

Виоланте Пласидо

Поскольку я чувствую, что как актеры мы должны быть уязвимыми, это часть нашей работы.

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

Расика Дугал

То, что это плохо, не означает, что оно того не стоит.

Калеб Дрессель

Держитесь подальше от наркотиков. Они того не стоят. Я пробовал, но ни один из них того не стоит.

Рэнди Ньюман

Каждый раз, когда я начинаю волноваться из-за чего-то, я просто думаю про себя: «Неужели это будет иметь значение в моей жизни завтра, через час, через год?» Ты просто не можешь напрягаться из-за мелочей, потому что в конце концов это того не стоит.

Кайли Дженнер

У меня был момент плохого мальчика в подростковом возрасте. Я никогда не буду делать это снова. Это было неприятно, и я усвоил урок.

Это было сексуально и загадочно, и это было похоже на «Посмотрите, какие они крутые», но оно того не стоило. Он лгал мне и обвинял меня в измене, но потом я понял, что это он изменял.

Джессика Бил

Все семейные посиделки, я слишком устал или не могу, потому что это конфликтует с работой… У меня семеро внуков. Я скучаю по сольным концертам и выпускным. По мне так оно того просто не стоит. Есть лучший способ прожить жизнь.

Дэймон Уэйанс

Мой руководящий принцип при написании с другими людьми заключается в том, что не стоит давать кому-то песню, если только мне не больно давать им эту песню.

Джош Тиллман

Когда тебе приходится работать и существовать среди циничного, выгоревшего персонала на съемочной площадке, неважно, что ты снимаешь или сколько тебе платят — оно того не стоит.

Генри Роллинз

«Быть ​​внутри» — это страсть. Жизнь коротка. Есть так много интересных вещей, которые мы можем сделать в нашей жизни, и я чувствую, что если кто-то просто появляется, это ничего не стоит ни для него, ни для нас.

Брэд Гарлингхаус

Доступные мужчины того не стоят.

Нилам Котари

Люди, которых я тренирую, очень успешны, поэтому победителям очень трудно не побеждать постоянно. Даже если это банально и того не стоит, мы все равно хотим побеждать — потому что мы любим побеждать. Это очень глубокая привычка.

Маршалл Голдсмит

У меня определенно был опыт, когда я долгое время преследовал кого-то, с кем у меня просто явно не было связи, поэтому я всегда как бы менялся для нее, но потом вы понимаете, что это того не стоит. В чем смысл?

Логан Лерман

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

Джаз Дженнингс

У Ангуса было несколько замахов на меня, может быть, два или три раза за всю нашу карьеру. Но потом дело сделано, и это не затянется, потому что оно того не стоит. Мы должны держаться вместе. И мы это знаем.

Малкольм Янг

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

Майк Паттон

Если это насилует меня физически, то мне оно того не стоит. Всегда найдется другая работа, на которой вам не придется раздеваться или говорить гадости.

Пенни Джонсон Джеральд

Но если вы не можете получать удовольствие от таких больших игр, то оно того не стоит.

Миля Единак ​​

Конечно, я люблю болтать с разными актерами о процессе и о том, как они это делают. По мне, если его нет на камере, если его нет, то оно того не стоит. Это действительно просто того не стоит.

Роберт Карлайл

Я не буду делиться всем, ни в своем выступлении, ни в интервью. Некоторые из людей, которые становятся самыми известными, больше всего откровенны, и я такой: «Нет, это просто не стоит для меня».

Ник Кролл

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

Венсан Кассель

Я не читаю комментарии, которые люди пишут обо мне — оно того не стоит.

Лаура Куэнсберг

Если вы собираетесь получить удары по лицу, удары локтями, порезы, удары, травмы, вам придется сбросить вес, придется поставить себя на грань смерти, чтобы явиться на следующий день и попытаться продемонстрировать свои способности. жизнь, ты должен любить ее. И если я не люблю это, это просто не стоит для меня.

Майкл Кьеза

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

Мириам Марголис

Мне просто не стоит мстить парню. Я имею в виду, это определенно отстой в то время, но очевидно, что ты не должен быть с этим человеком.

Кэрри Андервуд

Вы не отправляетесь в космос только ради науки. Экономически оно того не стоит. Я думаю, что причина, по которой мы должны быть в космосе, заключается в исследовании; это человеческие усилия.

Хелен Шарман

«Сумерки» погубили меня. Когда все это закончится, мне будет очень тяжело летать за границу. Просто не стоит покупать билет первого класса из-за его стоимости.

Эшли Грин

Я так нервничал каждый раз, когда был на сцене. Мне потребовалось много-много лет, чтобы прийти к тому моменту, когда я понял: «Хорошо, если я собираюсь продолжать это делать, я должен помнить, что это должно быть весело».

Я должен перестать так сильно давить на себя, потому что иначе оно того не стоит». И я до сих пор слишком критична к себе.

Дэйв Франко

Стоит прийти на церемонию вручения наград, если вы знаете, что выиграли ее, но, поскольку вы никогда не знаете, это того не стоит.

Артур Смит

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

Николь Полицци

Убивать себя ради получения зарплаты не стоит.

Наргис Фахри

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

Марко ван Бастен

Если вы делаете что-то, чем вы искренне не увлечены, это немного сокрушает душу. Просто не стоит.

Клэр Дэйнс

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

Антуан Фукуа

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

Энн Пауэрс

Есть так много симпатичных винтажных платьев из синтетики 60-х и 70-х годов, но они такие чешущиеся и горячие. Это того не стоит!

Зои Дешанель

Мои волосы слишком тонкие, чтобы их обесцвечивать. У меня столько ломкости, что красить не стоит.

Криста Б. Аллен

Я работал с Шоном Уильямом Скоттом над «Образцами для подражания», и у него руки в татуировках. Ему пришлось прийти на съемочную площадку на полтора часа раньше, чтобы их прикрыть. Это того не стоит. Я хочу этот дополнительный час сна.

Кристофер Минц-Плассе

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

Адам Ричман

Чтобы сделать фильм, требуется много времени, много энергии, сосредоточенности и самоотверженности, и это того не стоит, если вы собираетесь быть несчастным хотя бы день.

Бри Ларсон

Я никогда не сдавался. Времена, когда я бросал в прошлом, потому что не мог больше стараться, остались со мной, и чувство вины того не стоит.

Лиззи Армитстед

Я участник тренировочного поля Studio City. У них есть небольшое поле AstroTurf пар-3 и тренировочное поле. Знаешь, я не состою на поле, потому что не очень много играю в гольф, так что мне не стоит вступать в клуб.

Кевин Нилон

Я соревновался с другом из-за парня, но я всегда был тем, кто уступал. Не стоит драться с другом из-за парня.

Миган Джетт Мартин

Когда я заказываю бутерброды или кофе, я не называю своего имени: я говорю «Дэвид» или что-то в этом роде. Это того не стоит. Они никогда не портят «Дэвида». Я просто хочу свой бутерброд; Я просто хочу свой кофе.

Теннис Сандгрен

Не стоит зацикливаться на том, как вы выглядите, что на вас надето или когда вы возвращаетесь домой.

Джули Фуди

Конечно, вы можете сделать что-то пенистое и смешное, но вы, вероятно, должны быть уверены, что это будет безошибочный хит. Тогда это разумно, потому что позволяет снимать фильмы меньшего размера. Но если вы делаете что-то пенистое и смешное, что не работает, оно того не стоит.

Пол Беттани

Краска и новый пол — это просто освежение. Но не стоит обновлять все кухонные шкафы, если все та же неудачная планировка.

Джонатан Скотт

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

Прю Лейт

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

Джей-Джей Окоча

Я собираюсь драться на поле за «Ньюкасл», и если дойдет до того, что кто-то скажет, можешь ли ты драться за Англию, тогда я буду драться за Англию. Но я не собираюсь продолжать об этом. Это того не стоит.

Сол Кэмпбелл

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

Арло Паркс

Мой первый раз в переодевании был на Прайде. Я королева гордости. Это была катастрофа. Короткий ответ заключается в том, что вы можете это сделать, но вы создадите бестактность. Не надо, повторяю, не надевать на Прайд высокие каблуки. Не делай этого. Это того не стоит. Только не делай этого с собой, дорогая.

Боб Дравести Королева

Если я когда-нибудь вернусь в UFC, нам придется пересматривать контракт, потому что у меня все еще осталось три боя, и мне просто не стоит возвращаться туда. Если бы мы закончили тем, что поговорили и пересмотрели условия, и это того стоило для меня, я мог бы подумать об этом.

Чад Мендес

Идиоматический запрос: Слишком много усилий, но отдача настолько мала, что это не стоило усилий

спросил

Изменено 4 года назад

Просмотрено 54к раз

Я ищу идиому.

Вы приложили слишком много усилий, но прибыли так мало, что это не стоило бы усилий.

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

  • идиомы
  • идиомы-запросы

5

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

Ответ Кристины хороший. Еще одна фраза, которую можно применить, — это ложная экономия . Из определения Википедии:

Ложная экономия — это действие, которое вначале экономит деньги, но которое в течение более длительного периода времени приводит к тому, что больше денег тратится или тратится впустую, чем сберегается.

Сок не стоит выжимать.

Можно говорить о убывающей отдаче .

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

В более неформальном смысле это выражение просто относится к тому, что вы упомянули в своем вопросе: слишком мало пользы от усилий, до такой степени, что это не стоит усилий .

Словарь M-W ссылается на оба эти значения с этими определениями, даже используя слово усилие в своем определении:

убывающая доходность
1 : норма дохода, которая после определенного момента не может увеличиваться пропорционально дополнительным вложениям труда или капитала
2 : выгоды, которые после определенного момента перестают увеличиваться пропорционально приложенным усилиям

Викисловарь упоминает, что фраза равна идиоматический , в то время как поисковик фраз дает это примечание:

В обычном понимании «точка убывающей отдачи» — это предполагаемая точка, в которой дополнительные усилия или инвестиции в данном начинании не принесут соответственно возрастающих результатов. Итак, когда вы достигли этой точки, лучше отказаться от попытки.

Коллинз перечисляет этот пример предложения, показывая фразу, используемую газетой Глазго в более неформальном смысле:

Снова став поп-дивой, она оживила свою карьеру, которая в середине 1990-х была упражнением в уменьшении отдачи.

Другой дубль: Пиррова победа

Google определяет Пиррову победу как:

Победа такой разрушительной ценой, что она равносильна поражению.

Игра не стоит свеч ,

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

Однако эта идиома теряет актуальность после изобретения электрического освещения. См. Нграм.

1

Вы могли бы использовать довольно буквальную фразу, это стоит больше, чем .

Напр.

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

Это наводит меня на мысль о чем-то вроде «[вы] крутите [ваши] колеса», имея в виду расход энергии, который не дает желаемого результата, но тем не менее это то, на что вы бы потратили энергию. Я понимаю, что вы ищете идиому, описывающую трату своего времени и усилий в лучшем случае в виде нулевой суммы, поэтому, возможно, фраза, начинающаяся со слов «Несмотря на все [благие] намерения, [агент не был вознагражден за эти усердные усилия ].»

или «Несмотря на все [благие] намерения и цели…»

«Ограбление Питера, чтобы заплатить Полу» почему-то пришло на ум, но вы не поняли этого значения из того, что вы описали.

Здесь, в моем районе, моя группа друзей использует термин «ты слишком много делаешь» и его вариации как идиому, чтобы точно сказать, о чем вы спрашиваете. Буквально то, что вы спросили, дает точное определение термина, который мои друзья и я постоянно используем, который я так давно хотел, но не мог описать, что мы значим для моих родителей, поскольку мы подростки в колледже (начали использовать термин несколько лет назад, хотя). Этот термин часто используется для обобщения человека в настоящем, поэтому во многих случаях он используется в настоящем времени, независимо от того, когда произошло действие, определяющее кого-то как «слишком многого», но только в контексте того, что уже было сказано, что это такое. акт был. Идиома вообще специально используется как способ выразить то, что, по вашему мнению, не стоит делать что-то столь тривиальное. В результате это обычно используется, чтобы слегка подшутить над кем-то, принизив действие, которое они совершили, даже если это действие было оправдано с его / ее точки зрения (например, «вы прошли 2 мили до магазина и обратно только за молоком». ? Вы делаете максимум.»). С точки зрения этого человека, поступок может быть оправдан для него, даже если он согласен с тем, что поступок глуп, потому что, возможно, его заставили это сделать (их родители могли заставить его доить молоко, а у него не было). машина, поэтому им приходилось идти пешком), так что это обычно не используется специально как способ унизить кого-то. Однако, даже если этот термин используется для обозначения совершенного действия, даже в том же контексте, что и в примере, он не должен высмеивать человека, с которым разговаривают, если говорящий признает, что то, что он/она делал, было оправдано с их точки зрения (т. е. «ваши родители заставили вас пройти весь путь до магазина, 2 мили, под дождем за молоком? вы? Это делает maxxxx», нацеленный на само действие и используемый в согласии, сочувственном контексте).

С течением времени термин «делать слишком много» эволюционировал, чтобы также работать с вариациями с синонимами, чтобы обеспечить разнообразие в том, что мы говорим, и показать индивидуальное отличие от других, чтобы мы не казались одинаковыми, говоря одно и то же все время. время (потому что мы так часто используем его из-за того, что он так хорошо подходит для многих ситуаций). Например: «Сделай больше всего» — в настоящее время мы не так часто используем его, но он был замечен в поп-культуре, поэтому он может использоваться другими в других областях.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *