Класс Python для статических / экземпляров по умолчанию - PullRequest
1 голос
/ 28 июля 2011

На самом деле это два вопроса:

1) В чем заключается логика того факта, что при объявлении класса python переменные по умолчанию равны static, а методы - экземпляру по умолчанию?Я знаю, что могу объявить переменные в _ init _ или добавить @staticmethod или @classmethod к методам, чтобы перевернуть их на другую сторону, но мне кажется (по крайней мере, мне), что они оба последовательно по умолчанию в одну сторонуили другой (например, как Java / C #) будет иметь гораздо больше смысла.

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

2) Есть ли способобъявить переменные экземпляра в классах Python, не помещая их в _ init _ ?

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

A) объявить их самому или

B) вручную вызвать базовые классы _ init _ ,

, оба из которых - боль.Я мог бы сделать это, но это кажется грязным;подклассам что-то должно требовать ничего, кроме (BaseClass) в объявлении класса для работы, им не нужно вызывать что-то особенное в своих собственных _ init _ , чтобы функциональность BaseClass работала полностью

Ответы [ 2 ]

3 голосов
/ 28 июля 2011

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

class Parent(object):
  someAttr = Parser() # Static variable - created as the class is parsed.

  def __init__(self):
    self.otherAttr = Reader() # Instance - created when the class is instantiated.

class Child(Parent): pass

Дочерний объект будет иметь статический someAttr, а также экземпляр otherAttr, поскольку он не переопределяет метод __init__ из родительского элемента. Вам не нужно, чтобы каждый дочерний класс создавал одинаковые переменные экземпляра, если он не требует специальной обработки __init__. Он автоматически позвонит родителю __init__, если он не предоставил свой собственный. Надеюсь, это прояснит некоторые.

2 голосов
/ 28 июля 2011

1) Подход Python для реализации классов очень отличается от языков, таких как Java и C #.Он очень гибкий, и вы можете переопределять и изменять почти каждую часть его поведения, фактически вы можете контролировать реализацию их работы.

Атрибуты класса - это просто объекты, которые живут в пространстве имен класса.Сами объекты определяют поведение при доступе из экземпляра или класса, это происходит через так называемый протокол дескриптора.Объекты, которые не реализуют протокол дескриптора, действуют как то, что вы называете «статическими» объектами (например, доступ только для чтения из класса и экземпляра одинаков).Такие объекты, как функции, объекты методов класса, свойства реализуют этот протокол.

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

  • Функции хотятдействуют как методы
  • Свойства хотят позволить вам определить, как действует атрибут
  • Статические методы удаляют любое пользовательское поведение (объекты staticmethod просто переносят объект функции и отключают протокол дескриптора; они могут переносить любой объект)

2) Вы всегда должны вызывать __init__ суперкласса (в отличие от родительского класса).Обычно это делается с помощью super(CurrentClass, self).__init__(*args, **kwargs)

...