Класс и объект в Python
View more Tutorials:
Python - это procedural-oriented (процедурно-ориентированный) язык программирования, а также язык object oriented (объектно-ориентированного) программирования.
Процедурно-ориентированный (Procedural-oriented)
Процедурная ориентированность выражается в использовании функций в Python. Вы можете определить функции, и эти функции могут быть использованы в других модулях в программе Python.
Объектно-ориентированный (Object Oriented)

"Объектно-ориентированный" в Python выражается в использовании класса, вы можете определить класс, класс является прототипом (prototype) для создания объектов (object/instance).
Синтаксис для создания класса:
** class syntax **
class ClassName: 'Brief description of the class (Optional)' # Code ...
- Для определения класса используется ключевое слово class, за которым следует имя класса и двоеточие (:). Первая строка в теле класса представляет собой строку (string), которая кратко описывает этот класс. (Необязательно), вы можете получить доступ к этой строке через ClassName .__ doc__
- В теле класса вы можете объявлять атрибуты (attributes), методы (methods) и конструкторы (constructors).
Атрибуты (Attribute):
Атрибут является членом класса. Например, прямоугольник имеет два атрибута, включая width (ширину) и height (высоту).
Методы (Method):
- Метод класса похож на обычную функцию, но это функция класса, чтобы использовать его, вам нужно вызвать объект.
- Первым параметром метода всегда является self (ключевое слово, относящееся к самому классу).
Конструктор (Сonstructor):
- Constructor - это специальный метод класса, который всегда называется __init__.
- Первым параметром конструктора всегда является self (ключевое слово ссылается на сам класс).
- Constructor используется для создания объекта.
- Constructor присваивает значения параметра свойствам объекта, который будет создан.
- Вы можете определить максимум один коструктор (constructor) в классе.
- Если класс е определен конструктором (constructor), то Python по умолчанию считает его унаследованным от коструктора (constructor) родительского класса.

rectangle.py
# Класс симулирующий прямоугольник. class Rectangle : 'This is Rectangle class' # Метод, используемый для создания объект (Contructor). def __init__(self, width, height): self.width= width self.height = height def getWidth(self): return self.width def getHeight(self): return self.height # Метод расчитывающий площадь. def getArea(self): return self.width * self.height
Создание объекта из класса Rectangle:

testRectangle.py
from rectangle import Rectangle # Создать 2 объекта: r1 & r2 r1 = Rectangle(10,5) r2 = Rectangle(20,11) print ("r1.width = ", r1.width) print ("r1.height = ", r1.height) print ("r1.getWidth() = ", r1.getWidth()) print ("r1.getArea() = ", r1.getArea()) print ("-----------------") print ("r2.width = ", r2.width) print ("r2.height = ", r2.height) print ("r2.getWidth() = ", r2.getWidth()) print ("r2.getArea() = ", r2.getArea())

Что произойдёт когда вы создаёте объект из класса?
Когда вы создаете объект класса Rectangle, конструктор (constructor) этого класса будет вызван для создания объекта, а атрибутам объекта будет присвоено значение из параметра. Это похоже на приведенную ниже иллюстрацию:

В отличие от других языков, класс в Python имеет только один конструктор (constructor). Тем не менее, Python позволяет параметру иметь значение по умолчанию.
Примечание: Все необходимые параметры (required parameters) должны предшествовать всем параметрам со значениями по умолчанию.
person.py
class Person : # Параметр age и gender имеют значения по умолчанию. def __init__ (self, name, age = 1, gender = "Male" ): self.name = name self.age = age self.gender= gender def showInfo(self): print ("Name: ", self.name) print ("Age: ", self.age) print ("Gender: ", self.gender)
Например:
testPerson.py
from person import Person # Создать объект Person. aimee = Person("Aimee", 21, "Female") aimee.showInfo() print (" --------------- ") # age, gender по умолчанию. alice = Person( "Alice" ) alice.showInfo() print (" --------------- ") # gender по умолчанию. tran = Person("Tran", 37) tran.showInfo()

В Python, когда вы создаете объект через конструктор (constructor), будет создан реальный объект в памяти, он имеет определенный адрес.
Оператор, назначенный объекту AA объектом BB, не создает в памяти нового объекта, он просто указывает адрес AA к адресу BB.
Оператор, назначенный объекту AA объектом BB, не создает в памяти нового объекта, он просто указывает адрес AA к адресу BB.

== Оператор, используемый для сравнения двух объектов, указывающих на него, возвращает True, если два объекта указывают на один и тот же адрес в памяти. Оператор ! = так же используется для сравнения двух адресов двух объектов, на которые указывает, он возвращает True, если два объекта указывают на два разных адреса.
compareObject.py
from rectangle import Rectangle r1 = Rectangle(20, 10) r2 = Rectangle(20 , 10) r3 = r1 # Сравнить адрес r1 и r2 test1 = r1 == r2 # --> False # Сравнить адрес r1 и r3 test2 = r1 == r3 # --> True print ("r1 == r2 ? ", test1) print ("r1 == r3 ? ", test2) print (" -------------- ") print ("r1 != r2 ? ", r1 != r2) print ("r1 != r3 ? ", r1 != r3)

В Python есть 2 схожих понятия, которые вам нужно различать:
- Атрибут (Attribute)
- Переменная класса
Чтобы упростить это, давайте проанализируем пример ниже:
player.py
class Player: # Переменная класса. minAge = 18 maxAge = 50 def __init__(self, name, age): self.name = name self.age = age

Атрибут (attribute):
Объекты, созданные из одного класса, будут расположены по разным адресам в памяти (memory), а их атрибуты «одинаковое название» также имеют разные адреса в памяти. Как в изображении ниже:

testAttributePlayer.py
from player import Player player1 = Player("Tom", 20) player2 = Player("Jerry", 20) print ("player1.name = ", player1.name) print ("player1.age = ", player1.age) print ("player2.name = ", player2.name) print ("player2.age = ", player2.age) print (" ------------ ") print ("Assign new value to player1.age = 21 ") # Прикрепить значение атрибуту (attribute) age принадлежащий player1. player1.age = 21 print ("player1.name = ", player1.name) print ("player1.age = ", player1.age) print ("player2.name = ", player2.name) print ("player2.age = ", player2.age)

Python позволяет вам создать новый атрибут для уже существующего объекта. Например, объект player1 и новый атрибут, названный address.

testNewAttributePlayer.py
from player import Player player1 = Player("Tom", 20) player2 = Player("Jerry", 20) # Создать атрибут с названием 'address' для player1. player1.address = "USA" print ("player1.name = ", player1.name) print ("player1.age = ", player1.age) print ("player1.address = ", player1.address) print (" ------------------- ") print ("player2.name = ", player2.name) print ("player2.age = ", player2.age) # player2 не имеет атрибута 'address' (Ошибка происходит здесь). print ("player2.address = ", player2.address)

Как правило, вы получаете доступ к атрибуту объекта через оператор "точка" (например, player1.name). Однако Python позволяет вам иметь к ним доступчерез функцию (function).
Function (функция) | Описание |
getattr(obj, name[, default]) | Возвращает значение атрибута или возвращает значение по умолчанию, если объект не имеет этого атрибута. |
hasattr(obj,name) | Проверяет, имеет ли этот объект атрибут, указанный параметром «name», или нет. |
setattr(obj,name,value) | Устанавливает значение атрибута. Если атрибут не существует, он будет создан. |
delattr(obj, name) | Удаляет атрибут. |
testAttFunctions.py
from player import Player player1 = Player("Tom", 20) # getattr(obj, name[, default]) print ("getattr(player1,'name') = " , getattr(player1,"name") ) print ("setattr(player1,'age', 21): ") # setattr(obj,name,value) setattr(player1,"age", 21) print ("player1.age = ", player1.age) # Проверить имеет ли player1 атрибут (attribute) address или нет? hasAddress = hasattr(player1, "address") print ("hasattr(player1, 'address') ? ", hasAddress) # Создать атрибут 'address' для обхекта 'player1'. print ("Create attribute 'address' for object 'player1'") setattr(player1, 'address', "USA") print ("player1.address = ", player1.address) # Удалить атрибут 'address'. delattr(player1, "address")

Классы Python являются потомками класса object. Поэтому они наследуют следующие атрибуты:
Атрибут | Описание |
__dict__ | Информация про этот класс легко описана как словарь (Dictionary) |
__doc__ | Возвращает в строчку описания класса, или в None если она не имеет значение. |
__class__ | Возвращает объект, содержащий информацию класса, этот объект имеет много полезных атрибутов, один из которых__name__. |
__module__ | Возвращает имя модуля (module) класса, или возвращает к "__main__" если этот класс был определён в работающем модуле. |
testBuildInAttributes.py
class Customer : 'This is Customer class' def __init__(self, name, phone, address): self.name = name self.phone = phone self.address = address john = Customer("John",1234567, "USA") print ("john.__dict__ = ", john.__dict__) print ("john.__doc__ = ", john.__doc__) print ("john.__class__ = ", john.__class__) print ("john.__class__.__name__ = ", john.__class__.__name__) print ("john.__module__ = ", john.__module__)

В Python понятие "Переменная класса" (Class's Variable) эквивалентна понятию статического поля (Static Field) для других языков, таких как Java, CSharp. Доступ к переменным класса можно получить через имя класса или объект.

Совет здесь - вам стоит получить доступ к "Переменной класса" через имя класса вместо объекта. Это помогает избежать путаницы между "Переменной класса" и атрибутом.
Каждая переменная класса имеет адрес в памяти (memory). Он используется совместно со всеми объектами класса.

testVariablePlayer.py
from player import Player player1 = Player("Tom", 20) player2 = Player("Jerry", 20) # Получить доступ через название класса. print ("Player.minAge = ", Player.minAge) # Получить доступ через обхект. print ("player1.minAge = ", player1.minAge) print ("player2.minAge = ", player2.minAge) print (" ------------ ") print ("Assign new value to minAge via class name, and print..") # Прикрепить новое значение для minAge через класс. Player.minAge = 19 print ("Player.minAge = ", Player.minAge) print ("player1.minAge = ", player1.minAge) print ("player2.minAge = ", player2.minAge)

Python предоставляет вам функцию dir, эта функция дает список методов, атрибутов, переменных класса или объекта.
testDirFunction.py
from player import Player # Распечатать список атрибутов (attribute), методов и переменных класса Player. print ( dir(Player) ) print ("\n\n") player1 = Player("Tom", 20) player1.address ="USA" # Распечатать список атрибутов, методов и переменных обхекта 'player1'. print ( dir(player1) )
Запуск примера:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'maxAge', 'minAge']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address', 'age', 'maxAge', 'minAge', 'name']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address', 'age', 'maxAge', 'minAge', 'name']
- TODO