{"id":212,"date":"2024-01-25T16:08:10","date_gmt":"2024-01-25T16:08:10","guid":{"rendered":"https:\/\/learnpython.elegantwallp.com\/?p=212"},"modified":"2024-01-25T16:08:12","modified_gmt":"2024-01-25T16:08:12","slug":"python-__new__","status":"publish","type":"post","link":"https:\/\/learnpython.elegantwallp.com\/2024\/01\/25\/python-__new__\/","title":{"rendered":"Python __new__"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you\u2019ll learn about the Python __new__ method and understand how Python uses it to create a new object.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to the Python __new__ method<\/h2>\n\n\n\n<p>When you create an instance of a\u00a0class, Python first calls the\u00a0<code>__new__()<\/code>\u00a0method to create the object and then calls the\u00a0<code>__init__()<\/code>\u00a0method to initialize the object\u2019s attributes.<\/p>\n\n\n\n<p>The\u00a0<code>__new__()<\/code>\u00a0is a\u00a0static method\u00a0of the\u00a0<code>object<\/code>\u00a0class. It has the following signature:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>object.__new__(class, *args, **kwargs)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The first argument of the&nbsp;<code>__new__<\/code>&nbsp;method is the&nbsp;<code>class<\/code>&nbsp;of the new object that you want to create.<\/p>\n\n\n\n<p>The&nbsp;<code>*args<\/code>&nbsp;and&nbsp;<code>**kwargs<\/code>&nbsp;parameters must match the parameters of the&nbsp;<code>__init__()<\/code>&nbsp;of the class. However, the&nbsp;<code>__new__()<\/code>&nbsp;method does use them.<\/p>\n\n\n\n<p>The&nbsp;<code>__new__()<\/code>&nbsp;method should return a new object of the class. But it doesn\u2019t have to.<\/p>\n\n\n\n<p>When you define a new class, that class implicitly inherits from the&nbsp;<code>object<\/code>&nbsp;class. It means that you can override the&nbsp;<code>__new__<\/code>&nbsp;static method and do something before and after creating a new instance of the class.<\/p>\n\n\n\n<p>To create the object of a class, you call the&nbsp;<code>super().__new__()<\/code>&nbsp;method.<\/p>\n\n\n\n<p>Technically, you can call the&nbsp;<code>object.__new__()<\/code>&nbsp;method to create an object manually. However, you need to call the&nbsp;<code>__init__()<\/code>&nbsp;yourself manually after. Python will not call the&nbsp;<code>__init__()<\/code>&nbsp;method automatically if you explicitly create a new object using the&nbsp;<code>object.__new__()<\/code>&nbsp;method.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Python __new__ method example<\/h2>\n\n\n\n<p>The following defines the\u00a0<code>Person<\/code>\u00a0class with the\u00a0<code>name<\/code>\u00a0attribute and create a new instance of the\u00a0<code>Person<\/code>\u00a0class:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class Person: def __init__(self, name): self.name = name person = Person('John')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>In Python, a class is\u00a0callable. When you call the class to create a new object:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>person = Person('John')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Python will call the\u00a0<code>__new__()<\/code>\u00a0and\u00a0<code>__init__()<\/code>\u00a0methods. It\u2019s equivalent to the following method calls:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>person = object.__new__(Person, 'John') person.__init__('John')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The following shows the contents of the\u00a0<code>__dict__<\/code>\u00a0of the\u00a0<code>person<\/code>\u00a0object after calling the\u00a0<code>__new__()<\/code>\u00a0and\u00a0<code>__init__()<\/code>\u00a0methods:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>person = object.__new__(Person, 'John') print(person.__dict__) person.__init__('John') print(person.__dict__)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>{} {'name': 'John'}<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>As you can see clearly from the output, after calling the&nbsp;<code>__new__()<\/code>&nbsp;method, the&nbsp;<code>person.__dict__<\/code>&nbsp;is empty. And after calling the&nbsp;<code>__init__()<\/code>&nbsp;method, the&nbsp;<code>person.__dict__<\/code>&nbsp;contains the&nbsp;<code>name<\/code>&nbsp;attribute with the value \u2018<code>John'<\/code>.<\/p>\n\n\n\n<p>The following illustrates the sequence which Python calls the\u00a0<code>__new__<\/code>\u00a0and\u00a0<code>__init__<\/code>\u00a0method when you create a new object by calling the class:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>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')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>Creating a new Person object... Initializing the person object...<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>In this example, Python calls the __new__ method and the __init__ method after that.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When using the __new__ method<\/h2>\n\n\n\n<p>The following example defines the\u00a0<code>SquareNumber<\/code>\u00a0class that inherits from the built-in int type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class SquareNumber(int): def __new__(cls, value): return super().__new__(cls, value ** 2) x = SquareNumber(3) print(x) <em># 9<\/em><\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>In this example, the\u00a0<code>__new__()<\/code>\u00a0method of the\u00a0<code>SquareNumber<\/code>\u00a0class accepts an integer and returns the square number.\u00a0<code>x<\/code>\u00a0is an instance of the\u00a0<code>SquareNumber<\/code>\u00a0class and also an instance of the\u00a0<code>int<\/code>\u00a0built-in type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>print(isinstance(x, int)) <em># True<\/em><\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Note that you cannot do this by using the\u00a0<code>__init__()<\/code>\u00a0method because the\u00a0<code>__init__()<\/code>\u00a0method of the built-in\u00a0<code>int<\/code>\u00a0takes no argument. The following code will result in an error:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class SquareNumber(int): def __init__(self, value): super().__init__(value ** 2) x = SquareNumber(3)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Error:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>TypeError: object.__init__() takes exactly one argument (the instance to initialize)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>In practice, you use the&nbsp;<code>__new__()<\/code>&nbsp;method when you want to tweak the object at the instantiated time.<\/p>\n\n\n\n<p>For example, the following defines the\u00a0<code>Person<\/code>\u00a0class and uses the\u00a0<code>__new__<\/code>method to inject the\u00a0<code>full_name<\/code>\u00a0attribute to the Person\u2019s object:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class Person: def __new__(cls, first_name, last_name): <em># create a new object<\/em> obj = super().__new__(cls) <em># initialize attributes<\/em> obj.first_name = first_name obj.last_name = last_name <em># inject new attribute<\/em> obj.full_name = f'{first_name} {last_name}' return obj person = Person('John', 'Doe') print(person.full_name) print(person.__dict__)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>John Doe {'first_name': 'John', 'last_name': 'Doe', 'full_name': 'John Doe'}<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Typically, when you override the&nbsp;<code>__new__()<\/code>&nbsp;method, you don\u2019t need to define the&nbsp;<code>__init__()<\/code>&nbsp;method because everything you can do in the&nbsp;<code>__init__()<\/code>&nbsp;method, you can do it in the&nbsp;<code>__new__()<\/code>&nbsp;method.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you\u2019ll learn about the Python __new__ method and understand how Python uses it to create a new object. Introduction to the Python __new__ method When you create an instance of a\u00a0class, Python first calls the\u00a0__new__()\u00a0method to create the object and then calls the\u00a0__init__()\u00a0method to initialize the object\u2019s attributes. The\u00a0__new__()\u00a0is a\u00a0static method\u00a0of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32],"tags":[],"class_list":["post-212","post","type-post","status-publish","format-standard","hentry","category-8-metaprogramming-exceptions"],"_links":{"self":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/comments?post=212"}],"version-history":[{"count":1,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/212\/revisions"}],"predecessor-version":[{"id":213,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/212\/revisions\/213"}],"wp:attachment":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/media?parent=212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/categories?post=212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/tags?post=212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}