首页 > 其他 > 详细

类的内置方法

时间:2019-11-29 20:45:43      阅读:69      评论:0      收藏:0      [点我收藏+]

类的内置方法(魔法方法)

一、类的内置方法

  • 什么是类的内置方法
    • 凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法
    • 类的内置方法,会在某种条件满足下自动触发

内置方法如下

  • __new__:在__init__触发前,自动触发。
    • 调用该类时,内部会通过__new__产生一个新的对象
class Demo(object):
# 条件: __new__:在__init__触发前,自动触发
    def __new__(cls, *args, **kwargs):
        print('此处是__new__方法的执行')
        # python 内部通过object调用内部的__new__实现产生一个空的对象——>内存地址
        return object.__new__(cls, *args, **kwargs)
  • __init__:在调用类时自动触发。
    • 通过产生的对象自动调用__init__()
    # 条件:__init__:在调用类时自动触发
    def __init__(self):
        print('此处是__init__方法的执行')
        
demo_obj = Demo()
此处是__init__方法的执行
  • __getattr__:在"对象 . 属性"获取属性时,若"属性没有"时触发
    def __getattr__(self, item):
        print('此处是__getattr__方法的执行')
        print(item)
        #return '想要返回的值'
        return '自定义的值'

demo_obj = Demo()   # x
print(demo_obj.x)   # 自定义的值
  • __getattribute__:在"对象 . 属性"获取属性时,无论"属性有没有"都会触发
    def __getattribute__(self, item):
        print(item)
        # print(self.__dict__)
        # return self.__dict__[item]
        # 注意:此处不能通过"对象.属性",否则会产生递归调用,程序崩溃
        # getattr:内部调用了————> __getattribute__
        return (self, item)

注意:只要__getattr____getattribute__同时存在类的内部,只会触发后者

  • __setattr__当"对象 . 属性 = 属性值", 添加或修改属性时触发
    def __setattr__(self, key, value):
        print('此处是__setattr__方法的执行')
        print(key, value)
        # 出现递归
        # self.key = value
        # print(self.__dict__)
        # 此处是对 对象的名称空间——> 字典进行操作
        self.__dict__[key] = value
        
demo_obj = Demo()   # 此处是__setattr__方法的执行
demo_obj.x = 10     # x 10
print(demo_obj.x)   # 10
  • __call__在调用对象"对象+()"时触发
    def __call__(self, *args, **kwargs):
        print('此处是__call__方法的执行')
        # 调用对象时返回的值
        return [1, 2, 3, 4, 5]
    
demo_obj = Demo()
res = demo_obj()    # 此处是__call__方法的执行
print(res)          # [1, 2, 3, 4, 5]
print(demo_obj)     # <__main__.Demo object at 0x0000028DB3DA7B38>
  • __str__在打印对象时触发
    def __str__(self):
        print('此处是__str__方法的执行')
        return '111'
    
demo_obj = Demo()
print(demo_obj)

此处是__str__方法的执行
111

注意:该方法必须要有一个“字符串”返回值

  • __getitem__在对象通过“对象[key]”获取属性时触发
    def __getitem__(self, item):
        print('此处是__getitem__方法的执行')
        print(item)
        return self.__dict__[item]
    
print(demo_obj['x'])
print(demo_obj['y'])

x
10
y
20
  • __setitem__在对象通过“对象[key] = value值”设置属性时触发
    def __setitem__(self, key, value):
        print('此处是__setitem__方法的执行')
        print(key, value)
        # print(self.__dict__)
        # self.key = value    # {'key': value}
        # print(self.__dict__)
        self.__dict__[key] = value
        
demo_obj['y'] = 300
print(demo_obj.y)

此处是__setitem__方法的执行
y 300
300

二、单例模式

  • 什么是单例模式
    • 单例模式指的是在确定“类中的属性与方法”不变时,需要反复调用该类,产生不同的对象,会产生不同的内存地址,造成资源的浪费
    • 让所有类在实例化时,指向同一个内存地址,称之为单例模式
    • 无论产生多个对象,都会指向 单个 实例
  • 单例的优点
    • 节省内存空间
class Foo:
    def __init__(self, x, y):
        self.x = x
        self.y = y

foo_obj1 = Foo(10, 20)
print(foo_obj1.__dict__)    # {'x': 10, 'y': 20}
print(foo_obj1) # <__main__.Foo object at 0x000002085EF77B38>

foo_obj2 = Foo(10, 20)
print(foo_obj2.__dict__)    # {'x': 10, 'y': 20}
print(foo_obj2) # <__main__.Foo object at 0x000002085EF77D30>

这里就出现了重复调用类时,会产生不同内存地址的对象,造成资源浪费

import settings


# 通过 classmethod
class MySQL:
    # 一个默认值,用于判断对象是否存在,对象不存在证明值是None
    # __instance = None
    __instance = None

    def __init__(self, host, port):
        self.host = host
        self.port = port

    @classmethod
    def singleton(cls, host, port):
        # 判断__instance中若没有值,证明没有对象
        if not cls.__instance:
            # 产生一个对象并返回
            obj = cls(host, port)
            # None ---> obj
            cls.__instance = obj

        # 若__instance中有值,证明对象已经存在,则直接返回该对象
        return cls.__instance

    def start_mysql(self):
        print('启动mysql...')

    def close(self):
        print('关闭mysql...')


obj1 = MySQL.singleton(settings.HOST, settings.PORT)
print(obj1)
obj2 = MySQL.singleton(settings.HOST, settings.PORT)
print(obj2)
obj3 = MySQL.singleton(settings.HOST, settings.PORT)
print(obj3)
obj1.start_mysql()
obj1.close()

这样产生的对象会指向同一个内存地址,会节省内存空间

<__main__.MySQL object at 0x00000133FFB1F588>
<__main__.MySQL object at 0x00000133FFB1F588>
<__main__.MySQL object at 0x00000133FFB1F588>
启动mysql...
关闭mysql...

类的内置方法

原文:https://www.cnblogs.com/YGZICO/p/11959773.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!