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/
https://medium.com/better-programming/unlock-the-4-mysteries-of-self-in-python-d1913fbb8e16
'분석 Python > 구현 및 자료' 카테고리의 다른 글
[Python] 규칙이 있는 영어 한글 패턴 분리해보기 (0) | 2020.04.12 |
---|---|
[Python] dict 에서 RuntimeError: dictionary changed size during iteration 해결하는 방법 (0) | 2020.04.11 |
파이썬에서 정규성 검정하기 (0) | 2020.03.22 |
nvidia-smi 보다 더 자세한 정보를 알려주는 nvidia-htop + python script 확장자 없이 사용하기 (0) | 2020.03.05 |
[ Python ] 현재 Jupyter notebook의 Python Path는? (0) | 2020.02.08 |