Заметки по Python (14): расширенное объектно-ориентированное программирование

Python Технологии Nuggets призывают к публикации
Заметки по Python (14): расширенное объектно-ориентированное программирование

Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.

Привет всем, яодна чаша в неделю, передняя часть, которая не хочет быть пьяной (завернутой). Если написанной статье посчастливилось получить вашу благосклонность, мне очень повезло~

эталонная концепция

Цитировать (Reference) является указателем на объект

  • Ссылка — это указатель на реальный объект в памяти, представленный в виде имени переменной или адреса памяти.
  • Для каждого объекта существует по крайней мере одна ссылка,id()функция для получения ссылки
  • При передаче аргументов и присваиваний Python передает ссылку на объект вместо копирования объекта.

образец кода

list1 = [1, 2, 3, 4]
list2 = list1
print(id(list1))  # 2044656837192
print(id(list2))  # 2044656837192
# 因为list1是类的实例化,list2引用的是list1,两个都是引用的最基础的object类,所以两个的结果是一样的

Обработка ссылок внутренним механизмом Python

  • Неизменяемые объекты:immutableИнтерпретатор поддерживает как можно меньше областей памяти для одного и того же значения.
  • Изменяемые объекты:mutableИнтерпретатор поддерживает разные области памяти для каждого объекта.

Пример кода 1

text1 = "一碗周"
text2 = text1
text3 = "一碗周"
text4 = "一碗"
text5 = "周"
text6 = text4 + text5
print(id(text1))  # 1616972638288
print(id(text2))  # 1616972638288
print(id(text3))  # 1616972638288
print(id(text4))  # 1616973621272
print(id(text5))  # 1616973578032
print(id(text6))  # 1616974246288

Поскольку text1 и 2 относятся к строке, адрес памяти один и тот же, поскольку интерпретатор Python максимально экономит место в памяти, поэтому, когда значение неизменяемого типа совпадает, Python автоматически ссылается на адресное пространство. , для достижения цели экономии места, поэтому адресное пространство text1/2/3 согласовано; интерпретатор Python не оптимизирует адресное пространство для вычисляемого результата, даже если два значения совпадают, объясняет Python. процессор также откроет новое адресное пространство для вновь вычисленного результата

Пример кода 2

list1 = []
list2 = []
list3 = []
print(id(list1))  # 3204114440776
print(id(list2))  # 3204114440840
print(id(list3))  # 3204115873544

Каждый переменный объект имеет свое собственное независимое адресное пространство и не использует адресное пространство повторно.

Обычно есть 4 ситуации, в которых ссылка +1

  1. объект создан
  2. ссылка на объект
  3. Объекты используются в качестве аргументов функций или методов.
  4. Объекты рассматриваются как элементы в контейнере

Есть 4 вида ситуаций, которые приводят к цитированию -1

  1. объект удален
  2. Имя объекта присваивается новому объекту
  3. объект выходит за рамки
  4. Контейнер объекта удален

копия объекта

Копирование — это копирование объекта в новый объект, пространство памяти имеет «изменения», а копия делится на поверхностную и глубокую копии.

  • Поверхностное копирование: копирование только объекта верхнего уровня, метод копирования по умолчанию.
  • Глубокое копирование: итеративный метод копирования всех объектов.

Пример кода (мелкая копия 1)

list1 = ["甜甜", [1, 2, 3]]
list2 = list1.copy()  # 使用copy方法复制
list3 = list1[:]  # 使用切片复制
list4 = list(list1)  # 使用生成列表方式复制
for ch in [list1, list2, list3, list4]:
    for i in ch:
        print(i, id(i),  "\t", end="")  # 打印列表的没一项和id
    print(ch, id(ch))  # 打印每个列表和id
    
'''
---输出结果---
一碗周 2905817180184   [1, 2, 3] 2905787490888   ['一碗周', [1, 2, 3]] 2905787490952
一碗周 2905817180184   [1, 2, 3] 2905787490888   ['一碗周', [1, 2, 3]] 2905817092488
一碗周 2905817180184   [1, 2, 3] 2905787490888   ['一碗周', [1, 2, 3]] 2905817137800
一碗周 2905817180184   [1, 2, 3] 2905787490888   ['一碗周', [1, 2, 3]] 2905817771656
'''

Неглубокая копия копирует только пространство памяти слоя списка, а пространство памяти элементов внутри не будет скопировано.

Пример кода (мелкая копия 2)

list1 = ["一碗周", [1, 2, 3]]
list2 = list1.copy()  # 使用copy方法复制
list3 = list1[:]  # 使用切片复制
list4 = list(list1)  # 使用生成列表方式复制
list4[1].append(4)
print(list1)
print(list2)
print(list3)
print(list4)
'''
--输出结果--
['一碗周', [1, 2, 3, 4]]
['一碗周', [1, 2, 3, 4]]
['一碗周', [1, 2, 3, 4]]
['一碗周', [1, 2, 3, 4]]
'''

Здесь изменены только данные list4, но произошло содержимое всех списков; это связано с тем, что содержимое, на которое ссылается каждый список, одинаково, поэтому изменение одного или четырех из них изменится.

Глубокая копия должна использовать библиотеку копированияdeepcopy()Метод, итеративно копирует объекты на всех уровнях во внутренний слой объекта, полностью открывает пространство памяти для создания объектов и различных элементов объекта под объектом, глубокое копирование только для переменных категорий, иммутабельные типы не позволяют создавать новые объекты

образец кода

import copy  # 导入库
list1 = ["一碗周", [1, 2, 3]]
list2 = copy.deepcopy(list1)  # 使用copy库的deepcopy方法复制
for ch in [list1, list2]:
    for i in ch:
        print(i, id(i),  "\t", end="")  # 打印列表的没一项和id
    print(ch, id(ch))  # 打印每个列表和id

'''
---输出结果---
一碗周 2190823984184   [1, 2, 3] 2190853845832   ['一碗周', [1, 2, 3]] 2190853766728
一碗周 2190823984184   [1, 2, 3] 2190853961544   ['一碗周', [1, 2, 3]] 2190853961480
'''

Поскольку "сладкая" строка является неизменяемым типом, ее адресное пространство не изменится, а остальное адресное пространство изменилось.

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

Метод экземпляра также является ссылкой, которая является ссылкой на сам объект.Когда на метод ссылаются, метод (т. е. функция) создаст объект: объект метода

декоратор атрибутов класса

@propertyДекоратор может превратить метод во внешне видимое «свойство», которое представлено как метод внутри класса и свойство снаружи.

образец кода

class TestClass:
    def __init__(self, name):
        self.name = name

    @property    # 将方法转换为属性
    def age(self):
        return self.__age

    @age.setter  # 为属性进行赋值操作
    def age(self, value):
        if value < 0 or value > 110:
            value = 19
        self.__age = value


tt = TestClass("一碗周")
bb = TestClass("一碗粥")
tt.age = 18
bb.age = -19
print(tt.age)  # 18
print(bb.age)  # 19

искажение имени класса

искажение имени (Name Mangling) — это соглашение о преобразовании имени в классе, Python может выполнять некоторые важные функции посредством изменения имени, используя подчеркивание в Python._Чтобы выполнить модификацию имени, оно разделено на 5 случаев,

  • _name
  • name_
  • __name
  • __name__
  • _

_Украшение имени, начинающееся с одного подчеркивания

  • Одиночный атрибут или метод подчеркивания — это соглашение, используемое внутри класса, которое является соглашением, предусмотренным в PEP8.
  • Это просто соглашение, его еще можно принять<对象名>.<属性名>способ доступа
  • Разница в функции заключается в использованииfrom XX import *свойства или методы, начинающиеся с одного подчеркивания, не будут импортированы

образец кода

class TestClass:
    def __init__(self, name):
        self._name = name  # 约定在内部使用


tt = TestClass("一碗周")
print(tt._name)  # 一碗周

Хотя соглашение используется для внутреннего использования, к нему все же можно получить доступ.

_Изменение имени с одним подчеркиванием

Атрибуты или методы, оканчивающиеся одним символом подчеркивания, предназначены для предотвращения конфликтов с зарезервированными словами или существующими именами.Это также предусмотрено в PEP8.Это просто соглашение и не имеет соответствующей функции.

__Украшение имени, начинающееся с двойного подчеркивания

Свойства или методы, начинающиеся с двойного подчеркивания, будут переименованы интерпретатором, чтобы избежать конфликтов имен, это не соглашение, а функциональное,__namaбудет изменен на_<类名>__nameформа для реализации приватных свойств и приватных методов; это модификация имени класса, косвенно используемая как приватные свойства или приватные методы

__name__Изменение имени в начале и конце двойного подчеркивания

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

одно подчеркивание

Является ли единственное подчеркивание просто неуместным именем без специальной функции

Минимальный пустой класс для Python

эффект:

  • Класс — это пространство имен, в качестве пространства имен можно использовать наименьший пустой класс.

    • Минимальный пустой класс может помочь в хранении и использовании
    • Динамическое добавление атрибутов — это функция классов Python.

образец кода

class TestClass:
    pass


a = TestClass
a.text = "一碗周"
print(a.text)  # 一碗周
# 可以动态增加属性来达到存储信息的目的