betacode

Класс и объект в Python

  1. Объектно-ориентированный Python
  2. Создать класс в Python
  3. Параметры по умолчанию в Constructor
  4. Сравнение объектов
  5. Атрибут (Attribute)
  6. Функции с доступом в атрибут
  7. Готовые атрибуты класса
  8. Переменная класса
  9. Перечислить членов класса или объекта
  10. Уничтожить объект

1. Объектно-ориентированный Python

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

2. Создать класс в Python

Синтаксис для создания класса:
** 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) этого класса будет вызван для создания объекта, а атрибутам объекта будет присвоено значение из параметра. Это похоже на приведенную ниже иллюстрацию:

3. Параметры по умолчанию в 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()

4. Сравнение объектов

В Python, когда вы создаете объект через конструктор (constructor), будет создан реальный объект в памяти, он имеет определенный адрес.
Оператор, назначенный объекту 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)

5. Атрибут (Attribute)

В 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)

6. Функции с доступом в атрибут

Как правило, вы получаете доступ к атрибуту объекта через оператор "точка" (например, 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")

7. Готовые атрибуты класса

Классы 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__)

8. Переменная класса

В 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)

9. Перечислить членов класса или объекта

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']

10. Уничтожить объект

  • TODO