TelenkovDmitry 6 maanden geleden
bovenliggende
commit
df048e12cd
2 gewijzigde bestanden met toevoegingen van 220 en 0 verwijderingen
  1. 150 0
      courses/python_oop/meta/meta_1.py
  2. 70 0
      courses/python_oop/meta/meta_2.py

+ 150 - 0
courses/python_oop/meta/meta_1.py

@@ -0,0 +1,150 @@
+'''
+__new__ - вызывается для фактического создания нового объекта.
+Он статический, т.к. экземпляра класса еще не существует
+Метод __new__ не вызывает __init__.
+
+class object:
+
+    @staticmethod
+    def __new__(cls, *more):
+        pass
+'''
+
+class Point:
+    def __new__(cls, *args, **kwargs):
+        print('Point: Создание экземпляра')
+        instance = object.__new__(cls)
+        return instance
+    
+    def __init__(self, x, y):
+        print('Point: Инициализация экземпляра')
+        self.x = x
+        self.y = y
+
+
+def test_1():
+    p = object.__new__(Point)
+    p.__init__(10, 20)
+    print(p)
+    print(type(p))
+    print(p.__dict__)
+
+
+class Point3D(Point):
+    def __new__(cls, *args, **kwargs):
+        print('Point3D: Создание экземпляра')
+        instance = super().__new__(cls) # вызываем через super
+        return instance
+    
+    def __init__(self, x, y, z):
+        print('Point3D: Инициализация экземпляра')
+        super().__init__(x, y)
+        self.z = z
+
+
+def test_2():
+    p = Point3D(10, 20, 30)
+    print(p.__dict__)
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'''Создание атрибутов и методов в методе __new__'''
+
+class SquareNumber(int):
+    def __new__(cls, value):
+        return super().__new__(cls, value ** 2)
+    
+
+def test_3():
+    x = SquareNumber(3)
+    print(x)
+    print(isinstance(x, int))
+
+
+class Square:
+    def __new__(cls, w, h):
+        # Реализация метода area
+        cls.area = lambda self: self.width * self.height
+
+        setattr(cls, 'perimeter', lambda self: 2 * (self.width + self.height))
+        instance = super().__new__(cls)
+        instance.width = w
+        instance.height = h
+        return instance
+    
+    def __init__(self, w, h):
+        self.width = w
+        self.height = h
+
+
+def test_4():
+    s = Square(3, 4)
+    print(s)
+    print(s.area())
+    print(s.perimeter())
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+'''Вызов __new__ в качестве статического метода
+object.__new__(Square, 3, 4)
+Square.__new__(Square, 3, 4)
+'''
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+'''Возвращаемое значение метода __new__'''
+
+class Person:
+    def __new__(cls, *args, **kwargs):
+        print(f'Создание экземпляра {cls.__name__}')
+        instance = super().__new__(cls)
+        return instance
+    
+    def __init__(self):
+        print(f'Инициализация экземпляра {self.__class__.__name__}')
+
+def test_5():
+    p = Person()        
+
+'''
+Здесь вызов __inti__ не произойдет, т.к. __new__ 
+не возвращает экземпляр класаа
+'''
+class NewPerson:
+    def __new__(cls, *args, **kwargs):
+        print(f'Создание экземпляра {cls.__name__}')
+        instance = 'Hellow world'
+        return instance
+    
+    def __init__(self):
+        print(f'Инициализация экземпляра {self.__class__.__name__}')
+
+def test_6():
+    p = NewPerson()        
+
+
+class BestPerson:
+    def __new__(cls, name, age):
+        instance = super().__new__(cls)
+        instance.name = name
+        instance.age = age
+        return instance
+    
+def test_7():
+    p = BestPerson('Jackie Chan', 69)
+    print(p.__dict__)
+
+
+
+def main():
+    # test_1()
+    # test_2()
+    # test_3()
+    # test_4()
+    # test_5()
+    # test_6()
+    test_7()
+
+    
+
+if __name__ == '__main__':
+    main()

+ 70 - 0
courses/python_oop/meta/meta_2.py

@@ -0,0 +1,70 @@
+
+class Circle:
+    PI = 3.14
+
+    def __new__(cls, radius):
+        cls.get_area = lambda self: self._radius**2 * self.PI
+        cls.get_perimeter = lambda self: self.PI * self._diameter
+        cls.get_radius = lambda self: self._radius
+        cls.get_diameter = lambda self: self._diameter
+        instance = super().__new__(cls)
+        instance._radius = radius
+        instance._diameter = 2 * radius
+        return instance
+
+
+def test_1():
+    circle_instance = Circle(3.5)
+    print(f"Radius: {circle_instance.get_radius()}")
+    print(f"Diameter: {circle_instance.get_diameter()}")
+    print(f"Area: {circle_instance.get_area()}")
+    print(f"Perimeter: {circle_instance.get_perimeter()}")
+    
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class BaseConfig:
+    def __new__(cls, *args, **kwargs):
+        instance = super(BaseConfig, cls).__new__(cls)
+        instance.debug = False
+        instance.log_level = "INFO"
+        return instance
+
+class EmailConfig(BaseConfig):
+    def __new__(cls, *args, **kwargs):
+        instance = super().__new__(cls)
+        instance.smtp_server = 'smtp.gmail.com'
+        instance.smtp_port = 587
+        instance.username = 'boss_of_gym@gmail.com'
+        instance.password = ''
+        return instance
+
+class DatabaseConfig(BaseConfig):
+    def __new__(cls, *args, **kwargs):
+        instance = super().__new__(cls)
+        instance.db_host = '127.0.0.1'
+        instance.db_port = 5432
+        instance.db_name = 'cookies'
+        instance.db_user = 'admin'
+        instance.db_password = 'admin'
+        return instance
+
+def test_2():
+    email_config = EmailConfig()
+
+    print("SMTP server Configuration:")
+    print(f"Server: {email_config.smtp_server}")
+    print(f"Port: {email_config.smtp_port}")
+    print(f"User: {email_config.username}")
+    print(f"Password: {email_config.password}")
+    print(f"Debug: {email_config.debug}")
+    print(f"Logger: {email_config.log_level}")
+
+
+def main():
+    # test_1()
+    test_2()
+
+
+if __name__ == '__main__':
+    main()