Tuesday, May 24, 2022

Python __new__ documented per official manual

Когда вы создаете экземпляр класса, 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