装饰器,都可以装饰类内部的方法函数
classmethod :使该方法绑定给类来使用,称为类的绑定方法ui
staticmethod:使该方法变成了一个普通函数,即非绑定方法code
再来复习一下对象的绑定方法特殊之处对象
对象的绑定方法特殊之处:ip
- 由对象调用,会将对象当作第一个参数传入该方法内存
类的绑定方法特殊之处:md5
- 由类来调用,会将类名当作第一个参数传入该方法utf-8
上代码字符串
import settings import uuid import hashlib class People: def __init__(self,name,age): self.name = name self.age = age # 将该方法装饰成类的绑定方法 # 登陆认证,从配置文件中读取用户名密码 @classmethod def login_auth(cls): obj = cls(settings.USER,settings.PWD) return obj # 将该方法装饰成一个普通的函数,不会自动传值,对象or类均可以调用 @staticmethod def create_id(): uuid_obj = uuid.uuid4() return hashlib.md5(str(uuid_obj).encode("utf-8")).hexdigest() def index(self): print("验证经过,显示主页") # 用classmethod 装饰过的方法返回一个对象 obj = People.login_auth() # 在该方法中经过读取配置文件的参数实例化出一个对象 obj.index() # 将返回出去的对象调用其余方法 # 调用 staticmethod 装饰过的方法,即普通函数,由类调用,也能够对象调用 print(People.create_id())
python中内置的函数,均传入两个参数(参数1,参数2)
isinstance:判断一个对象是不是一个类的实例(判断一个对象是不是已知类型)
issubclass:判断一个类是不是另外一个类的子类。
class Foo: pass class Bar(Foo): pass # isinstance 判断对象是不是类的实例 f = Foo() print(isinstance(f,Foo)) # True l = [1,2] print(isinstance(l,list)) # True # issubclass 判断类是不是另外一个类的子类 print(issubclass(Bar,Foo)) # True
反射☞的是经过 “字符串” 对 对象或类的属性进行操做
hasattr:经过字符串,判断该字符串是不是对象或类的属性
getattr:经过字符串,获取对象或类的属性
setattr:经过字符串,设置对象或类的属性
delattr:经过字符串,删除对象或类的属性
上代码
class People: country = "China" def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex # hasattr 传两个参数,判断对象有没有属性 p1 = People("qinyj",18,"nan") print(hasattr(p1,"country")) # True # getattr 传三个参数,也能够传两个参数,若是属性不存在报错 p2 = People("qinyj",18,"nan") print(getattr(p2,"country","China")) # setattr 传两个参数,设置对象的属性 p3 = People("qinyj",18,"nan") setattr(p3,"country","China") print(getattr(p3,"country",)) # delattr 传两个参数,删除对象的属性 p4 = People("qinyj",18,"nan") # delattr(p4,"country") # print(getattr(p4,"country",))
# 反射练习 class Movie: def input_cmd(self): print("请输入命令") while True: cmd = input("请输入执行的方法名").strip() # hasattr 与 getattr 连用实例 if hasattr(self,cmd): getattr(self,cmd)() def upload(self): print("电影开始上传") def download(self): print("电影开始下载") m = Movie() m.input_cmd()
凡是在类内部定义,"__名字__
"的方法都称之为魔法方法,又称类的内置方法
__init__
:初始化函数,在类调用时自动触发
__str__
:打印对象的时候自动触发
__del__
:删除对象的名称空间,最后才执行
__getattr__
:对象.属性获取属性,没有获取到值自动触发
__setattr__
:对象.属性赋值的时候自动触发
__call__
:在帝乡被调用时自动触发
__new__
:在__init__
前自动触发,产生一个空的对象
class Foo(object): ''' 如下均是类的内置方法, ''' def __new__(cls, *args, **kwargs): print(cls) return object.__new__(cls) # 产生一个空的对象 def __init__(self): print("在类调用时触发") def __str__(self): return "在打印对象的值时触发" def __del__(self): print("最后执行该方法,删除内存地址") def __getattr__(self, item): return "没有获取对象属性时触发" def __setattr__(self, key, value): print("设置对象属性值时触发") print(key,value) self.__dict__[key] = value def __call__(self, *args, **kwargs): print("调用对象时触发") f = Foo() # 打印对象 print(f) # <class '__main__.Foo'> # 在类调用时触发 # 在打印对象的值时触发 # 最后执行该方法,删除内存地址 # 获取对象属性x print(f.x) # <class '__main__.Foo'> # 在类调用时触发 # 在打印对象的值时触发 # 没有获取对象属性时触发 # 最后执行该方法,删除内存地址 # 对象赋值新的属性 f.x = "x" print(f.x) # <class '__main__.Foo'> # 在类调用时触发 # 在打印对象的值时触发 # 没有获取对象属性时触发 # 设置对象属性值时触发 # x x # x # 最后执行该方法,删除内存地址 # 对象调用 f() # <class '__main__.Foo'> # 在类调用时触发 # 在打印对象的值时触发 # 没有获取对象属性时触发 # 设置对象属性值时触发 # x x # x # 调用对象时触发 # 最后执行该方法,删除内存地址 class MyFile: def __init__(self,file_name,mode="r",encoding="utf-8"): self.file_name = file_name self.mode = mode self.encoding = encoding def file_open(self): self.f = open(self.file_name,self.mode,encoding=self.encoding) def file_read(self): res = self.f.read() print(res) # 使用del内置函数,在最后执行,就会调用关闭文件操做 def __del__(self): self.f.close() print("文件关闭成功") f = MyFile("settings.py") f.file_open() f.file_read() print("程序结束,对象将被销毁!")
单例模式指的是单个实例,实例指的是调用类产生的对象
实例化多个对象时会产生不一样的内存地址,单例可让全部调用者,在调用类产生对象的状况下都指向同一分内存地址,例如,打开文件
单例模式目的:为了减小内存占用
class File: __instance = None # 单例模式1 # 使用类的绑定方法, @classmethod def singleton(cls,file_name): # 类中设置一个私有属性__instance, # 在类本身调用完成产生一个对象,将这个对象赋值给类的这个属性, # 若是这个类属性有对象了,就说明已经实例化过了无需再次实例化,直接返回 # 外部调用者只需调用其方法便可使用单例模式操做对象 if not cls.__instance: obj = cls(file_name) cls.__instance = obj return cls.__instance # 单例模式2 # 使用__new__产生一个空的对象,至关于建立一个空的对象,调用时至关于多个变量指向这个对象 def __new__(cls, *args, **kwargs): if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance ''' 实例化出来的对象内存地址同样 <__main__.File object at 0x000000000295C668> <__main__.File object at 0x000000000295C668> <__main__.File object at 0x000000000295C668> ''' def __init__(self,file_name,mode="r",encoding="utf-8"): self.file_name = file_name self.mode = mode self.encoding = encoding def open(self): self.f = open(self.file_name,self.mode,encoding=self.encoding) def read(self): res = self.f.read() print(res) # def __del__(self): # self.f.close() f1 = File("settings.py") f2 = File("settings.py") f3 = File("settings.py") print(f1) print(f2) print(f3) # 以下:产生的三个对象 内存地址均不一样 # <__main__.File object at 0x000000000298C6D8> # <__main__.File object at 0x000000000298C710> # <__main__.File object at 0x000000000298C6A0> # 让其成为单例模式调用 f1 = File.singleton("settings.py") f2 = File.singleton("settings.py") f3 = File.singleton("settings.py") print(f1) print(f2) print(f3) # 以下:产生的三个对象 内存地址均相同 # <__main__.File object at 0x0000000009F6F908> # <__main__.File object at 0x0000000009F6F908> # <__main__.File object at 0x0000000009F6F908>