[Python] self 에 대해서 알아보기 (__init__ , __new__)

2020. 4. 9. 23:39분석 Python/구현 및 자료

광고 한 번씩 눌러주세요! 블로그 운영에 큰 힘이 됩니다 :)

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def greet(self, other):
        print(f'{self.name} says hello to {other}.')

Person instance object가 어떻게 생성되는지에 대한 예시가 있다.

person = Person('John Smith', 25)
print(person.__dict__)

`__dict__` 속성을 호출하면, 객체 `person`에는 `name` 과 `age`가 있다.

What’s self in the __init__() method? 이 글 참고 

 

person.greet('Mary')

Person.greet(person, 'Mary')

위의 같이 할 수도 있지만, `Person`이라는 클래스를 사용하여, `person` , `Mary` 는  `self` , `other` argument로 설정된다. 

이렇ㄱ

`Person`을 만들기 위해서.__init__(self, name, age) 작업, 먼저 self argument로 설정된 인스턴스 객체를 찾아야 한다. 즉, 이 생성자 방식에서 사용할 수 있는 인스턴스 객체가 이미 다른 무언가가 생성되었다. 

The __new__() method

 

another_person = object.__new__(Person)
another_person.__dict__

Person.__init__(another_person, 'Ruby Green', 5)
another_person.__dict__

위에 보여지는 것처럼  class `Person`을 통해서  `__new__()` 방법을 호출한다. 그래서 초기 생성 후에, 인스턴트 객체는 아무런 속성을 가지고 있지 않다. 이 인스턴스 객체를 `self` argument으로 사용하여 마침내 클래스 Person을 사용하여 __init__() 메서드를 호출하여 이름과 연령 속성을 가진 인스턴스를 완전히 초기화할 수 있게 되었다.

class Student:
    def __new__(cls):
        print('__new__ gets called.')
    
    def __init__(self):
        print('__init__ gets called.')

여기서 type을 보면 NoneType으로 나온다는 것을 알 수 있다. 왜냐하면 __new__만 호출되고 __init__는 호출되지 않았기 때문이다. 

As a side note, one thing to mention is that the __new__()  method takes an argument called cls
, which is the class for which we want to create an instance object. This argument is named  cls
, which is just a convention in Python, the same as the argument named  self in an instance method (i.e., the 
greet() method in the example above).

 

class Student:
    def __new__(cls):
        print('__new__ gets called.')
        student = object.__new__(cls)
        return student
    def __init__(self):
        print('__init__ gets called.')

이번에 업데이된 `__new__()`에 새로운 `Student` class의 객체를 반환한다. 

What if __init__ has other arguments?

class Student:
    def __new__(cls, *args):
        print('__new__ gets called.')
        student = object.__new__(cls)
        return student
    def __init__(self,name,id_number):
        self.name = name
        self.id_number = id_number
        print('__init__ gets called.')

막상 신기해서 쓰게 됐는데, 왜 하는지에 대해서 의문이 들게 돼서 찾아보니 이런 이유가 있다고 한다.

Usually it’s uncommon to override __new__ method, but some times it is required if you are writing APIs or customizing class or instance creation or abstracting something using classes.

The __new__ method is also used in conjunction with meta classes to customize class creation

오... cls  객체 만드는 개수를 제한할 수 있다.

class LimitedInstances(object):
    _instances = []  # Keep track of instance reference
    limit = 3
    def __new__(cls, *args, **kwargs):
        print(cls.limit)
        print(cls._instances)
        if not len(cls._instances) <= cls.limit:
            raise RuntimeError("Count not create instance. Limit %s reached" % cls.limit    )
        instance = object.__new__(cls, *args, **kwargs)
        cls._instances.append(instance)
        return instance
    
    def __del__(self):
        # Remove instance from _instances 
        self._instance.remove(self)
for _ in range(10) :
    a = LimitedInstances()

class AbstractClass(object):
    def __new__(cls, a, b):
        instance = super(AbstractClass, cls).__new__(cls)
        instance.__init__(a,b)
        return 3
    def __init__(self, a, b):
        print("Initializing Instance", a, b)
        

신기하게 a 가 class가 아니라 return되는 것이 3이니까 3이 출력된다.

 

https://howto.lintel.in/python-__new__-magic-method-explained/

 

Python: __new__ magic method explained - Lintel Technologies Blog

Python is Object oriented language, every thing is an object in python. Python is having special type of  methods called magic methods named with preceded and trailing double underscores. When we talk about magic method __new__ we also need to talk about _

howto.lintel.in

https://medium.com/better-programming/understand-python-custom-class-instantiation-beyond-init-85ad1cbe90d

 

Understand Python Custom Class Instantiation, Beyond __init__()

How Python instantiates a custom class object

medium.com

https://medium.com/better-programming/unlock-the-4-mysteries-of-self-in-python-d1913fbb8e16

 

Unlock the 4 Mysteries of self in Python

Using self in Python

medium.com

 

728x90