类的使用

一、类的内置方法(魔术方法)

类的内置方法:

​ 凡是在类内部定义,以__ 开头 __ 结尾 (如__ init __) 的方法都是类的内置 方法,也称为魔术方法

​ 类的内置方法,会在某种条件满足下自动触发。

内置方法如下:

​ __ new __ __:在 __ __ init __触发前,自动触发,调用该类时,内部会通过

__ new__ 产生一个新的对象。

​ __ init __ :在调用类时自动触发。通过产生的对象调用 __ init __ ()

# 1
class Demo(object):
    #条件:__new__: 在__init__前自动触发
    def __new__(cls, *args, **kwargs):
        print('此处是__new__方法的执行')
        #python内部通过object调用内部的__new__实现产生一个空的对象---->内存地址
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print('此处是__init__方法的执行')


demo_obj = Demo()
print(demo_obj)  #<__main__.Demo object at 0x103d887f0>
'''
结果:
此处是__new__方法的执行
此处是__init__方法的执行
<__main__.Demo object at 0x103d887f0>
'''
# 2
class Demo1(object):
    #__getattr__:在'对象.属性'获取属性时,若'属性没有'时触发
    def __getattr__(self, item):
        print('此处是__getattr__方法的执行')
        print(item)
        #return 想要返回的值
        return 'tank is very very handsome'

demo1_obj = Demo1()
print(demo1_obj.x, '想要返回的值')
'''
结果:
此处是__getattr__方法的执行
x
tank is very very handsome 想要返回的值
'''
demo1_obj.x = 10
print(demo1_obj.x, '属性有时不会触发__getattr__...')
'''
结果:
10 属性有时不会触发__getattr__...
'''
#3
#条件:__getattribute__ :在'对象.属性'获取属性时,无论'属性有没有'都会触发。
class Demo2(object):
    def __getattribute__(self, item):
        print(item, '<----打印属性名字')
        return self
        # return self.__dict__[item]  #递归,死循坏
        #注意此处不能通过 对象.属性,否则会产生递归调用,程序崩溃
        #getattr:内部调用了----->__getattribute__
        #return getattr(self, item)
    #注意:只要__getattr__ 与__getattribute__ 同时存在类的内部,只会触发__getattribute__

demo_obj2 = Demo2()
print(demo_obj2.x)
'''
结果:
x <----打印属性名字
<__main__.Demo2 object at 0x1088516d0>
'''

#4
# 条件:当'对象.属性 = 属性值',添加或修改属性时触发
class Demo3(object):
    def __init__(self):
        pass
    def __setattr__(self, key, value): #key---->对象.属性名  value----> 属性值
        print('此处是__setattr__方法的执行')
        print(key, value)
    #出现递归
    #self.key = value
    #print(self.__dict__)
    #此处是对对象的名称空间---》字典进行操作
        self.__dict__[key] = value
#原来设置属性时,会自动触发父类中的__setattr__, 内部为对象添加x属性,值为20
demo_obj3 = Demo3()
print(demo_obj3.__dict__)#{}
demo_obj3.x = 10
print(demo_obj3)        #此处是__setattr__方法的执行
                        #x 10
                        #<__main__.Demo3 object at 0x10fe006d0>
print(demo_obj3.__dict__)  #{'x': 10}

# 5
# 条件:在打印对象时触发
# 注意:该方法必须要有一个'字符串'返回值
class Demo4(object):
    def __str__(self):
        print('此处是__str__方法的执行')
        return '111'  #如果没有返回值时会报错

demo_obj4 = Demo4()
print(demo_obj4)  #111,

# 6
# #条件:在调用对象 '对象+()'时触发
class Demo5(object):
    def __call__(self, *args, **kwargs):
        print('此处是__call__方法的执行')
        #调用对象时返回的值
        return [1,2,3,4,5]
demo_obj5 = Demo5()
print(demo_obj5())  #此处是__call__方法的执行
                    #[1, 2, 3, 4, 5]
# 7
# 在对象通过'对象[key]'获取属性时触发
class Demo6(object):
    def __getitem__(self, item):
        print('此处是__getitem__方法的执行')
        print(item)
        return self.__dict__[item]

demo6_obj = Demo6()
demo6_obj.x = 10
print(demo6_obj['x'])
'''
结果:
此处是__getitem__方法的执行
x
10
'''
#8
#在对象通过'对象[key] = value'设置属性时触发
class Demo7(object):
    def __setitem__(self, key, value):
        print('此处是__setitem__方法的执行')
        print(key, value)
        print(self.__dict__)
        self.key = value
        print(self.__dict__)
        self.__dict__[key] = value
demo7_obj = Demo7()
demo7_obj['x']= 10
'''
结果:
此处是__setitem__方法的执行
x 10
{}
{'key': 10}
'''

单例模式:

​ -单例模式是一种设计模式

​ -指的是在确定‘’类中的属性与方法‘’不变时,需要反复用该类,让所有的对象都执行同一个内存地址

优点:节省内存空间

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 0x10dfe86d0>
foo_obj2 = Foo(10, 20)
print(foo_obj2.__dict__)  ##{'x': 10, 'y': 20}
print(foo_obj2)  #<__main__.Foo object at 0x10065e910>

单例模式方法:

​ 1.通过classmethod

​ 2.通过装饰器实现

​ 3.通过__ new __ 实现

​ 4.通过导入模块实现

​ 5.通过元类实现

import setting

#通过classmethod
class MySQL:
    #一个默认是,用来判断对象是否存在,对象不存在证明值是None
    #__instance 是类的属性,可以由类来调用
    __instance = None #--->执行到代码
    #__instacne = obj
    def __init__(self, host, port):

        self.host = host
        self.port = port
    @classmethod
    def singlethon(cls,host,port): #单例方法 ----》类方法
        print('cls:',cls)
        #判断__instance中没有值,证明没有对象
        if not cls.__instance:
            #产生一个对象并返回
            obj = cls(host, port)
            print('obj:',obj)
            #此时的None转变为obj
            cls.__instance = obj
            return obj
        #若__instance 中有值,证明对象已经存在。证明对象已经存在,则直接返回对象
        else:
            return cls.__instance

    def start_mysql(self):
            print('启动mysql')
    def close(self):
            print('关闭mysql')

obj1 = MySQL.singlethon(setting.host, setting.port)
print(obj1)
obj1.start_mysql()
obj2 = MySQL.singlethon(setting.host, setting.port)
print(obj2)
print(obj2.__dict__)
obj3 = MySQL.singlethon(setting.host, setting.port)
print(obj3)     #<__main__.MySQL object at 0x11034acd0>
print(obj3.__dict__)        #{'host': '192.168.0.0', 'port': 7070}
原文地址:https://www.cnblogs.com/xy-han/p/11983223.html