Может ли переменная класса python использоваться как переменная класса и экземпляра? [Дубликат]

Это очень распространенная проблема, с которой мы сталкиваемся, борясь с «таинствами» JavaScript.

Давайте начнем с простой функции JavaScript:

function foo(){
// do something 
 return 'wohoo';
}

let bar = foo(); // bar is 'wohoo' here

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

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

function foo(){
 setTimeout( ()=>{
   return 'wohoo';
  }, 1000 )
}

let bar = foo() // bar is undefined here

Итак, вы идете, эта задержка просто сломала функциональность, которую мы ожидали! Но что именно произошло? Ну, на самом деле это довольно логично, если вы посмотрите на код. функция foo() после выполнения ничего не возвращает (таким образом, возвращаемое значение равно undefined), но оно запускает таймер, который выполняет функцию после 1s, чтобы вернуть «wohoo». Но, как вы можете видеть, значение, присвоенное бару, является немедленно возвращенным материалом из foo (), а не что-либо еще, что приходит позже.

Итак, как мы решаем эту проблему?

Давайте попросим нашу функцию для ОБЕЩАНИЯ. Обещание действительно о том, что это означает: это означает, что функция гарантирует, что вы предоставите любой результат, который он получит в будущем. поэтому давайте посмотрим на это в нашей маленькой проблеме выше:

function foo(){
   return new Promise( (resolve, reject) => { // I want foo() to PROMISE me something
    setTimeout ( function(){ 
      // promise is RESOLVED , when exececution reaches this line of code
       resolve('wohoo')// After 1 second, RESOLVE the promise with value 'wohoo'
    }, 1000 )
  })
}

let bar ; 
foo().then( res => {
 bar = res;
 console.log(bar) // will print 'wohoo'
});

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

5
задан Martijn Pieters 15 December 2014 в 01:40
поделиться

3 ответа

Магия.

Нет, действительно.

Классы Python не имеют встроенной структуры, как на C ++. Они сами, просто объекты - экземпляры другого типа:

class Foo(object):
    pass

print(type(Foo))  # <class 'type'>

Вы даже можете сделать класс, как если бы вы сделали любой другой объект, вызвав type. Это:

class Bar(object):
    a = 1
    b = 2

Действительно (более или менее) синтаксический сахар для этого:

Bar = type('Bar', (object,), {'a': 1, 'b': 2})

type берет имя вашего нового класса, список его суперклассов , и dict всех атрибутов класса и выплескивает новый класс.

Но, поскольку type - это просто класс, как любой другой, возможно подкласс и придать ему другое поведение. И это то, что сделал Django: он создал подкласс type, который делает что-то другое с атрибутом атрибутов, которые вы ему передаете.

Вы не видите, что это происходит непосредственно в вашем собственном коде, но если вы проверите type(models.Model), вы узнаете, что его тип не type, а что-то особенное для Django. Вероятно, он имеет «мета» в названии, потому что он называется метаклассом : классом класса.

Это довольно распространенный шаблон для создания «декларативных» библиотек в Python , где атрибуты класса фактически определяют некоторую структуру. Вы можете видеть то же самое в валидации формы (wtforms), валидации схемы (дуршлаг), других ORM (sqlalchemy) и даже модуле перечисления stdlib.

0
ответ дан Eevee 24 August 2018 в 10:25
поделиться

Модели Django используют метакласс для изменения поведения нормального класса.

Используйте dir(Question), и вы увидите, что теперь есть различные атрибуты этого класса. Это обычное поведение только для моделей Django.

Если вам интересно, вы можете изучить метод метакласса __new__ , но он делает lot работы, специфичной для задач реляционного сопоставления объектов.

3
ответ дан Community 24 August 2018 в 10:25
поделиться

Вопрос - это объект типа типа. Вам нужен экземпляр вопроса:

>>> q= Question(text = "Does a dog have the buddha nature?")

Тогда вы должны получить

q.text «У собаки есть природа будды?»

Обратите внимание, что этот объект не будет сохраняться, если вы не сохраните ():

>>> q.save()
1
ответ дан Jon Kiparsky 24 August 2018 в 10:25
поделиться
Другие вопросы по тегам:

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