Учебники

Объектно-ориентированный Python — Строительные блоки

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

Классовые комплекты: поведение и состояние

Класс позволит вам связать воедино поведение и состояние объекта. Обратите внимание на следующую диаграмму для лучшего понимания —

Связки

Следующие пункты заслуживают внимания при обсуждении групповых классов —

  • Слово « поведение» идентично функции — это кусок кода, который что-то делает (или реализует поведение)

  • Слово состояние идентично переменным — это место для хранения значений в классе.

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

Слово « поведение» идентично функции — это кусок кода, который что-то делает (или реализует поведение)

Слово состояние идентично переменным — это место для хранения значений в классе.

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

Классы имеют методы и атрибуты

В Python создание метода определяет поведение класса. Метод word — это имя ООП, данное функции, определенной в классе. Подводя итог —

  • Функции класса — это синоним методов

  • Переменные класса — это синоним атрибутов имени.

  • Класс — проект для экземпляра с точным поведением.

  • Объект — один из экземпляров класса, выполняющий функциональность, определенную в классе.

  • Тип — указывает класс, к которому принадлежит экземпляр

  • Атрибут — значение любого объекта: object.attribute

  • Метод — «вызываемый атрибут», определенный в классе

Функции класса — это синоним методов

Переменные класса — это синоним атрибутов имени.

Класс — проект для экземпляра с точным поведением.

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

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

Атрибут — значение любого объекта: object.attribute

Метод — «вызываемый атрибут», определенный в классе

Обратите внимание на следующий фрагмент кода, например:

var = Hello, John
print( type (var)) # ‘str’> or <class 'str'>
print(var.upper()) # upper() method is called, HELLO, JOHN

Создание и внедрение

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

class MyClass(object):
   pass
# Create first instance of MyClass
this_obj = MyClass()
print(this_obj)
# Another instance of MyClass
that_obj = MyClass()
print (that_obj)

Здесь мы создали класс MyClass, который не выполняет никаких задач. Объект аргумента в классе MyClass включает наследование класса и будет обсуждаться в следующих главах. pass в приведенном выше коде указывает, что этот блок пуст, то есть это определение пустого класса.

Давайте создадим экземпляр this_obj класса MyClass () и распечатаем его, как показано на рисунке —

<__main__.MyClass object at 0x03B08E10>
<__main__.MyClass object at 0x0369D390>

Здесь мы создали экземпляр MyClass. Шестнадцатеричный код относится к адресу, где хранится объект. Другой экземпляр указывает на другой адрес.

Теперь давайте определим одну переменную внутри класса MyClass () и получим переменную из экземпляра этого класса, как показано в следующем коде —

class MyClass(object):
   var = 9

# Create first instance of MyClass
this_obj = MyClass()
print(this_obj.var)

# Another instance of MyClass

that_obj = MyClass()
print (that_obj.var)

Выход

Вы можете наблюдать следующий вывод при выполнении кода, приведенного выше —

9
9

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

Методы экземпляра

Функция, определенная в классе, называется методом. Метод экземпляра требует экземпляр для его вызова и не требует декоратора. При создании метода экземпляра первым параметром всегда является self. Хотя мы можем назвать его (self) любым другим именем, рекомендуется использовать self, так как это соглашение об именах.

class MyClass(object):
   var = 9
   def firstM(self):
      print("hello, World")
obj = MyClass()
print(obj.var)
obj.firstM()

Выход

Вы можете наблюдать следующий вывод при выполнении кода, приведенного выше —

9
hello, World

Обратите внимание, что в приведенной выше программе мы определили метод с self в качестве аргумента. Но мы не можем вызвать метод, так как мы не объявили ему никакого аргумента.

class MyClass(object):
   def firstM(self):
      print("hello, World")
      print(self)
obj = MyClass()
obj.firstM()
print(obj)

Выход

Вы можете наблюдать следующий вывод при выполнении кода, приведенного выше —

hello, World
<__main__.MyClass object at 0x036A8E10>
<__main__.MyClass object at 0x036A8E10>

Инкапсуляция

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

  • Упрощает и облегчает понимание использования объекта, не зная внутренних органов.

  • Любое изменение может быть легко управляемым.

Упрощает и облегчает понимание использования объекта, не зная внутренних органов.

Любое изменение может быть легко управляемым.

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

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

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

class MyClass(object):
   def setAge(self, num):
      self.age = num

   def getAge(self):
      return self.age

zack = MyClass()
zack.setAge(45)
print(zack.getAge())

zack.setAge("Fourty Five")
print(zack.getAge())

Выход

Вы можете наблюдать следующий вывод при выполнении кода, приведенного выше —

45
Fourty Five

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

class MyClass(object):
   def setAge(self, num):
      self.age = num

   def getAge(self):
      return self.age
zack = MyClass()
zack.setAge(45)
print(zack.getAge())
zack.setAge("Fourty Five")
print(zack.getAge())

Ини Конструктор

Метод __ init __ вызывается неявно, как только создается экземпляр объекта класса. Это инициализирует объект.

x = MyClass()

Строка кода, показанная выше, создаст новый экземпляр и назначит этот объект локальной переменной x.

Операция создания экземпляра, которая вызывает объект класса , создает пустой объект. Многие классы любят создавать объекты с экземплярами, настроенными на конкретное начальное состояние. Следовательно, класс может определять специальный метод с именем __init __ (), как показано ниже.

def __init__(self):
   self.data = []

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

x = MyClass()

Метод __init __ () может иметь один или несколько аргументов для большей гибкости. Init обозначает инициализацию, поскольку инициализирует атрибуты экземпляра. Это называется конструктором класса.

class myclass(object):
   def __init__(self,aaa, bbb):
      self.a = aaa
      self.b = bbb

x = myclass(4.5, 3)
print(x.a, x.b)

Выход

4.5 3

Атрибуты класса

Атрибут, определенный в классе, называется «атрибуты класса», а атрибуты, определенные в функции, называются «атрибуты экземпляра». При определении эти атрибуты не имеют префикса self, так как они являются свойством класса, а не конкретного экземпляра.

Атрибуты класса могут быть доступны как самому классу (className.attributeName), так и экземплярам класса (inst.attributeName). Таким образом, экземпляры имеют доступ как к атрибуту экземпляра, так и к атрибутам класса.

>>> class myclass():
   age = 21
>>> myclass.age
21
>>> x = myclass()
>>> x.age
21
>>>

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

В Python есть путь поиска атрибутов. Сначала это метод, определенный в классе, а затем класс над ним.

>>> class myclass(object):
   classy = 'class value'
>>> dd = myclass()
>>> print (dd.classy) # This should return the string 'class value'
class value
>>>
>>> dd.classy = "Instance Value"
>>> print(dd.classy) # Return the string "Instance Value"
Instance Value
>>>
>>> # This will delete the value set for 'dd.classy' in the instance.
>>> del dd.classy
>>> >>> # Since the overriding attribute was deleted, this will print 'class
value'.

>>> print(dd.classy)
class value
>>>

Мы переопределяем классовый атрибут класса в экземпляре dd. Когда он переопределен, интерпретатор Python считывает переопределенное значение. Но как только новое значение удалено с помощью ‘del’, переопределенное значение больше не присутствует в экземпляре, и, следовательно, поиск поднимается на уровень выше и получает его из класса.

Работа с данными класса и экземпляра

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

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

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

class InstanceCounter(object):
   count = 0 # class attribute, will be accessible to all instances
   def __init__(self, val):
      self.val = val
      InstanceCounter.count +=1 # Increment the value of class attribute, accessible through class name
# In above line, class ('InstanceCounter') act as an object
   def set_val(self, newval):
      self.val = newval

   def get_val(self):
      return self.val

   def get_count(self):
      return InstanceCounter.count
a = InstanceCounter(9)
b = InstanceCounter(18)
c = InstanceCounter(27)

for obj in (a, b, c):
   print ('val of obj: %s' %(obj.get_val())) # Initialized value ( 9, 18, 27)
   print ('count: %s' %(obj.get_count())) # always 3

Выход

val of obj: 9
count: 3
val of obj: 18
count: 3
val of obj: 27
count: 3

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

class myClass:
   class_attribute = 99

   def class_method(self):
      self.instance_attribute = 'I am instance attribute'

print (myClass.__dict__)

Выход

Вы можете наблюдать следующий вывод при выполнении кода, приведенного выше —

{'__module__': '__main__', 'class_attribute': 99, 'class_method': , '__dict__': , '__weakref__': , '__doc__': None}

Атрибут экземпляра myClass .__ dict__ как показано —