Когда вы создаете экземпляр класса, Python сначала вызывает метод __new__() для создания объекта, а затем вызывает метод __init__() для инициализации атрибутов объекта.
__new__() — это статический метод класса объекта. Он имеет следующую запись:
object.__new__(class, *args, **kwargs)
==========================================
Первый аргумент метода __new__ — это класс нового объекта, который вы хотите создать.
Параметры *args и **kwargs должны совпадать с параметрами __init__() класса. Однако метод __new__() их использует. Метод __new__() должен возвращать новый объект класса. Но это не обязательно. Когда вы определяете новый класс, этот класс неявно наследуется от класса объекта. Это означает, что вы можете переопределить статический метод __new__ и сделать что-то до и после создания нового экземпляра класса. Чтобы создать объект класса, вы вызываете метод super().__new__(). Технически вы можете вызвать метод object.__new__() для создания объекта вручную. Однако после этого вам нужно вручную вызвать __init__(). Python не будет вызывать метод __init__() автоматически, если вы явно создаете новый объект с помощью метода object.__new__().
===========================================
Последовательность, в которой Python вызывает методы __new__ и __init__, когда вы создаете новый объект, вызывая класс:
(.env) boris@boris-All-Series:~/MASK$ cat classPerson.py
class Person:
def __new__(cls, name):
print(f'Creating a new {cls.__name__} object...')
obj = object.__new__(cls)
return obj
def __init__(self, name):
print(f'Initializing the person object...')
self.name = name
person = Person('John')
(.env) boris@boris-All-Series:~/MASK$ python3 classPerson.py
Creating a new Person object...
Initializing the person object...
===========================================
Например, следующее определяет класс Person и использует метод __new__ для внедрения
атрибута full_name в объект Person:
(.env) boris@boris-All-Series:~/MASK$ cat classPerson1.py
class Person:
def __new__(cls, first_name, last_name):
# create a new object
obj = super().__new__(cls)
# initialize attributes
obj.first_name = first_name
obj.last_name = last_name
# inject new attribute
obj.full_name = f'{first_name} {last_name}'
return obj
person = Person('John', 'Doe')
print(person.full_name)
print(person.__dict__)
(.env) boris@boris-All-Series:~/MASK$ python3 classPerson1.py
John Doe
{'first_name': 'John', 'last_name': 'Doe', 'full_name': 'John Doe'}
=========================================
В следующем примере определяется класс SquareNumber, который наследуется от встроенного типа int:
(.env) boris@boris-All-Series:~/MASK$ cat squareNumber.py
class SquareNumber(int):
def __new__(cls, value):
return super().__new__(cls, value ** 2)
x = SquareNumber(25)
print("x = ",x)
(.env) boris@boris-All-Series:~/MASK$ python3 squareNumber.py
x = 625
Итог:
__new__() — это статический метод класса объекта.Когда вы создаете новый объект, вызывая класс, Python сначала вызывает метод __new__() для создания объекта, а затем вызывает метод __init__() для инициализации атрибутов объекта.Переопределите метод __new__(), если вы хотите настроить объект во время создания.
Целью __new__ является создание пустого экземпляра объекта, который затем инициализируется __init__. Переопределяя __new__, вы получаете полный контроль над создаваемым вами экземпляром, но не используете метод __init__ для дальнейшей обработки.
Автоматическое создание методов
предположим, вы хотите иметь класс с заданным набором свойств. Вы можете управлять инициализацией этих свойств с помощью кода, подобного этому.
На основании https://www.pythontutorial.net/
No comments:
Post a Comment