反射,魔法方法,单例模式
时间:2019-10-12 19:57:49
收藏:0
阅读:95
目录
1. 绑定方法
绑定方法就是在书写这个方法时,会有一个默认参数(作为第一个参数),绑定给类,这个参数就是
cls
,绑定给对象这个参数就是self
。绑定方法的特殊之处:
谁来调用这个绑定方法,就把谁当作第一个参数传给该方法
对象的绑定方法的特殊之处:
由对象来调用,会将对象当作第一个参数传给该方法
类的绑定方法的特殊之处:
由类来调用,会将类当作第一个参数传给该方法
2. 类内部方法的装饰器
- 之前还讲过的有
property
,作用是让这个方法不用加括号就可以调用。让它看起来就像是一个数据属性。
1. classmethod
classmethod
就是一个装饰器。装饰类内部的方法,使该方法绑定来使用。
2. staticmethod
staticmethod
也是一个装饰器。装饰类内部的方法。使该方法既不绑定给类,也不绑定给对象,此时就是作为普通函数。
3. uuid
模块
是一个加密模块,uuid中的uuid4方法通过时间戳生成一个世界上唯一的字符串对象(注意是对象,可以强制类型转换成字符串)。
应用实例:
import hashlib import uuid class Teacher: def __init__(self, user, pwd): self.user = user self.pwd = pwd # 主页 def index(self): if self.user == 'tank' and self.pwd == '123': print('验证通过,显示主页...') @classmethod def login_auth_from_settings(cls): obj = cls('tank', '123') return obj # Teacher() ---> return = obj @staticmethod def create_id(): # 生成一个唯一的id字符串 uuid_obj = uuid.uuid4() md5 = hashlib.md5() md5.update(str(uuid_obj).encode('utf-8')) return md5.hexdigest() obj = Teacher.login_auth_from_settings() obj.index() # 验证通过,显示主页... tea1 = Teacher('tank', '123') tea1.index() # 验证通过,显示主页... print(type(uuid.uuid4())) print(Teacher.create_id()) # 类调用这个普通函数 tea1 = Teacher('tank', '123') print(tea1.create_id()) # 对象调用这个普通函数
3.isinstance与issubclass
函数
他们都是python内置的函数。
isinstance
(参数1,参数2)判断参数1是否是参数2的一个实例
issubclass
判断参数1是否是参数2的子类
4. 反射
- 反射就是通过字符串来操作类或者对象的属性
- 反射本质就是在使用内置函数,其中反射有以下四个内置函数:
1. hasattr:判断一个方法是否存在与这个类中
使用方法:
hasattr(对象或类名,属性名)
2. getattr:根据字符串去获取obj对象里的对应的方法的内存地址,加"()"括号即可执行
例如:
使用方法:
foo = getattr(对象或类名,属性名1,默认值) 默认值可加可不加,没有默认值默认是None。和字典内置方法的get同样的用法。
若该属性为方法属性时:
foo() 就相当于——》 对象.属性名1()
3. setattr:通过setattr将外部的一个函数绑定到实例中
使用方法:
setattr(对象名或者类名,属性名,属性值)
遵循:有就修改,没有就添加
4. delattr:删除一个实例或者类中的方法
使用方法:
delattr(对象名或者类名,属性名)
5. 魔法方法
凡是在类内部定义,以“__开头__结尾”的方法都称之为魔法方法,又称“类的内置方法”。魔法方法会在某些条件成立时触发。
__init__: 在执行程序时遇到 调用类 时触发。
__str__: 会在执行程序时,遇到 打印对象 时触发。必须要有一个返回值, 该返回值必须是字符串类型
__del__: 对象被销毁前(有删除对象和程序执行结束时触发)
删除对象时,执行该方法。
程序执行要结束前执行该方法,该方法会在最后执行。
__getattr__: 会在执行程序时遇到 对象.属性 时,并且 “属性没有” 的情况下才会触发。
__setattr__: 会在执行程序时遇到 “对象.属性 = 属性值” 时触发。此时,这个赋值操作是失效的, 就是说没有对这个属性赋值。要想对一个属性赋值,可以使
用`对象.__dict__[属性名] = 属性值`方式新增属性或者修改属性。
__call__: 会在对象被调用时触发。只有类的内部有这个方法时,对象才能加括号进行对象调用,否则对 象加括号会报错。
__new__: 会在__init__执行前触发,如果当前类的__new__ 没有return 一个空对象,则不会触发 __init__。
6. 单例模式
1. 什么是单例模式
- 单例模式:基于某种方法实例化多次得到实例是同一个
2. 为什么用单例模式
- 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例
- 使用单例模式可以减少内存占用
3. 三种单例方式:(暂时没有一个方法 ,传相同参数时只产生一个对象,当传不同参数时,产生不同的对象)
(1)类内部定义 类的绑定方法
IP = '1.1.1.1'
PORT = 3306
class Mysql:
__instacne = None
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def from_conf(cls):
if cls.__instacne is None:
cls.__instacne = cls(IP, PORT) # 只能从此处传参
return cls.__instacne
obj1 = Mysql.from_conf()
obj2 = Mysql.from_conf()
obj3 = Mysql.from_conf()
print(obj1 is obj2 is obj3) # True
(2)类内部通过__new__
方法控制只创建一次空对象
- 这种方法使得产生的对象都是第一个对象。
IP = '1.1.1.1'
PORT = 3306
class Mysql:
__instance = None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
def __init__(self, ip, port):
self.ip = ip
self.port = port
# 除了最后一个对象的参数有意义,之前的参数都没有意义,所有对象都是第一个对象,但是属性都是使用最后一个实例化对象时传入的参数。
obj1 = Mysql(IP,PORT)
obj2= Mysql(IP,PORT)
obj3 = Mysql(55,66)
print(obj1 is obj2 is obj3) # True
(3)装饰器式的单例
IP = '1.1.1.1'
PORT = 3306
def singleton(cls):
cls.__instance = cls(IP, PORT) # 只能在这里传参
def wrapper(*args, **kwargs):
if len(args) == 0 and len(kwargs) == 0:
return cls.__instance
return cls(*args, **kwargs)
return wrapper
@singleton # Mysql = singleton(Mysql) # Mysql = wrapper
class Mysql:
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj1 = Mysql() # wrapper() # 这里和后面的都不能传参,如果传参,装饰器就什么事也没做,相当于没有装饰器。
obj2 = Mysql() # wrapper()
obj3 = Mysql() # wrapper()
print(obj1 is obj2 is obj3) # True
原文:https://www.cnblogs.com/Mcoming/p/11663354.html
评论(0)