2016-10-31 1 views
-1

Этот пример класса был взят из here.Проблемы с пониманием частных атрибутов в классах и метод свойств класса в Python 3

class Celsius: 
    def __init__(self, temperature = 0): 
     self.temperature = temperature 

    def to_fahrenheit(self): 
     return (self.temperature * 1.8) + 32 

    def get_temperature(self): 
     print("Getting value") 
     return self._temperature 

    def set_temperature(self, value): 
     if value < -273: 
      raise ValueError("Temperature below -273 is not possible") 
     print("Setting value") 
     self._temperature = value 

    temperature = property(get_temperature, set_temperature) 

Идея заключается в том, что, когда мы создаем экземпляр Цельсия и установите атрибут температуры (например, Foo = Цельс (-1000)), мы хотим, чтобы убедиться, что атрибут не меньше, чем -273 ДО установка атрибута температуры.

Я не понимаю, как это похоже на обход self.temperature = temperature и перейти прямо к последней строке. Мне кажется, что здесь создаются три атрибута/свойства: атрибут Class, temperature; атрибут Instance, temperature; и функцию set_temperature, которая устанавливает атрибут _temperature.

Что я понимаю, что последняя строка (оператор присваивания) должен выполнить код property(get_temperature, set_temperature), который запускает функция get_temperature и set_temperature и стажер устанавливает атрибут/свойство _temperature личного.

Кроме того, если я бегу: foo = Celsius(100), а затем foo.temperature, как результат foo.temperature наступающем из temperature = property(get_temperature, set_temperature) и, таким образом, _temperature И НЕ self.temperature = temperature? Почему даже есть self.temperature = temperature, если temperature = property(get_temperature, set_temperature) получает побег при каждом звонке foo.temperature?

Больше вопросов ...

Почему у нас есть два атрибута с тем же именем (например, температуры) и как код знать, чтобы получить значение _temperature когда foo.temperature называется?

Для чего нужны частные атрибуты/свойства, а не только температура?

Как получить set_temperature(self, value) атрибут для параметра value (например, аргумент, который заменяет value)?

Короче говоря, пожалуйста, объясните это мне, как трехлетнему, так как я только программировал несколько месяцев. Заранее спасибо!

+0

, когда 'Celcius.temperature' определяется как' свойство', он переопределяет поведение оператора 'self.temperature = ...' вместо вызова функции setter_temperature, поэтому никогда не возникает переменная экземпляра, называемая' температура' комплект. –

+0

Как это знать, чтобы переопределить утверждение 'self.temperature = temperature'? Потому что оба имеют одно и то же имя, температура? – tommyc38

+0

да, но более конкретно, потому что вы определили дескриптор в классе, когда вы делаете что-либо с тем же именем в экземпляре, дескриптор обрабатывает то, что на самом деле происходит. Точно так же с методами, если вы запустите 'print (self.get_temperature)', он показывает объект «bound_method» вместо самой функции, это потому, что функции также являются дескрипторами. –

ответ

2

Когда мы первый учил о классах/объектов/атрибутов нам часто говорят что-то вроде этого:

Когда вы смотрите атрибут как x.foo это первый смотрит, чтобы увидеть, если 'foo' является переменной экземпляра и возвращает его, если он не проверяет, 'foo' определен в классе x и возвращает его, в противном случае повышается AttributeError.

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

Дескриптор в основном определяет, что делать при поиске/установке атрибута какого-либо экземпляра, property - это реализация, которая позволяет вам определять свои собственные функции для вызова при получении/настройке/удалении атрибута.

Когда вы temperature = property(get_temperature, set_temperature) вы указываете, что когда x.temperature является извлекаться он должен вызвать x.get_temperature() и возвращаемое значение этого вызова будет то, что x.temperature имеет значение.

, указав set_temperature как setter собственности говорится, что когда-либо x.temperature является назначенной к чему-то он должен вызвать set_temperature со значением назначенным в качестве аргумента.

Я бы порекомендовал вам попробовать stepping through your code in pythontutor, он покажет вам, когда get_temerature и set_temperature вызываются после этих утверждений.

+0

Я также хотел бы обратиться к большой статье, которая помогла мне понять, что происходит [здесь] (http://nbviewer.jupyter.org/urls/gist.github.ком/ChrisBeaumont/5758381/сырье/descriptor_writeup.ipynb). Благодаря! – tommyc38

Смежные вопросы