Как эта функция с «доходностью» работает в деталях?

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

def _test_static_init(value):
    return value, value * 2

class Test:
    x, y = _test_static_init(20)

if __name__ == "__main__":
    print Test.x, Test.y

Старый, неправильный ответ:

Вот пример, я надеюсь, что это поможет:

class Test:
    x = None

    @classmethod
    def set_x_class(cls, value):
        Test.x = value

    def set_x_self(self):
        self.__class__.set_x_class(10)

if __name__ == "__main__":
    obj = Test()
    print Test.x
    obj.set_x_self()
    print Test.x
    obj.__class__.set_x_class(15)
    print Test.x

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

13
задан MickyD 26 November 2015 в 06:44
поделиться

3 ответа

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

Компилятор сгенерирует класс, реализующий IEnumerator, который имеет функцию MoveNext () и свойство Current. В классе будут все члены, необходимые для хранения состояния функции между вызовами. Точные подробности можно считать «Магией компилятора».

Объект этого сгенерированного класса будет обрабатываться и управляться Unity3d Engine. Unity3d Engine будет вызывать MoveNext () для каждой активной сопрограммы один раз в каждом кадре (если не указано иное).

Это позволило Unity3d Programmer писать сценарии, которые воспроизводятся по одному кадру за раз. Комбинация магии компилятора C # и магии Unity3d Engine приводит к очень мощным, но простым в использовании сценариям.

Чтобы ответить на ваш вопрос: код в вашей функции будет выполнен один раз, но он остановится на операторе yield return.

Как указано выше, специальный объект, реализующий IEnumerator, создается компилятором C #.

При первом вызове MoveNext () ваша функция создает взрыв и устанавливает для текущего объекта значение «new WaitForSeconds (1.5f)».

Механизм Unity3d проверяет этот объект, видит, что он является экземпляром специального класса «WaitForSeconds», поэтому помещает перечислитель в некоторую очередь ожидания и не запрашивает второй элемент, пока не пройдет 1,5 секунды. Тем временем будет обработано много кадров и воспроизведен взрыв.

Через 1,5 секунды Unity извлечет перечислитель из очереди и снова вызовет MoveNext (). Вторая часть вашей функции будет выполняться сейчас, но не сможет создать второй объект.MoveNext () вернет false, чтобы указать, что ему не удалось получить новый элемент, что является сигналом для Unity3d, чтобы выбросить этот перечислитель. Сборщик мусора в какой-то момент освободит память.

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

27
ответ дан 1 December 2019 в 19:49
поделиться

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

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

5
ответ дан 1 December 2019 в 19:49
поделиться

Лучше возвращать IEnumerable, а не IEnumerator, так как он более гибкий и простой в использовании. Еще лучше использовать IEnumerable. Yield return - это просто синтаксический сахар для реализации блока итераторов, компилятор генерирует соответствующий код, так как это по сути стандартный код, который можно легко сгенерировать программно. Обычно вы используете yield return, когда хотите, чтобы серия одиночных действий выглядела как коллекция, например:

public IEnumerable<Thing> GetThings()
{
    yield return GetNextThing();
}
1
ответ дан 1 December 2019 в 19:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: