目录
昨日内容
组合
- 一个类产生的对象时另一个对象的属性
- 目的:减少代码冗余
封装
把一堆属性封装到一个对象中
目的:方便存取(通过对象.属性的方式对数据进行存取)
-
如何封装
- 类内部定义
- 通过对象.属性的方式添加属性
-
访问限制机制
-
在类内部,凡是以__开头的属性都不能被外部直接访问,python对其作了变形(隐藏)
例如:__属性 变形为 __类名__属性
目的:防止使用者在外部对隐私数据进行访问,保护数据安全
-
property装饰器
用来装饰在类内部的函数中,使该方法不用加括号调用
多态
同种事物的多种形态
-
目的:让父类定义一套标准,子类遵循父类定义的标准
总结:为了统一类的编写规范
-
实现方式
- 子类继承父类,遵循父类的方法
- 子类继承抽象类,强制子类必须遵循父类的标准
- 鸭子类型
鸭子类型
- 只要看起来像鸭子,那么就是鸭子类型
- 在不知道对象是什么情况下,拥有相同的方法
今日内容
classmethod
- 类内部方法的装饰器,是该方法绑定给类使用(类的绑定方法)
- 作用:由类来调用,会将类当作第一个参数传给该方法
class People:
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def tell_info(cls):
print(cls)
p =People('wick',24)
p.tell_info()
People.tell_info()
staticmethod
- 类内部方法的装饰器,使该方法不与类和对象绑定
- 作用:类和对象调用,不用传参数
import uuid
import hashlib
class People:
def __init__(self,name,age):
self.name = name
self.age = age
@staticmethod
def create_id():
uuid_id = uuid.uuid4()
return uuid_id
p =People('wick',24)
print(p.create_id())
print(People.create_id())
面对对象高级
isinstance
python内置的函数,可以传入两个参数,用于判断参数1是否是参数2的一个实例(判断一个对象是否是一个类的实例)
class Foo:
pass
class Goo:
pass
foo_obj = Foo()
print(Foo.__dict__) # 获取当前类的属性
print(foo_obj.__class__) # 获取当前对象所属的类
print(isinstance(foo_obj,Foo)) # True
print(isinstance(foo_obj,Goo)) # False
issubclass
python内置函数,可以传入两个参数,用于判断参数1是否是参数2的子类(判断一个类是否是另一个类的子类)
class Foo:
pass
class Goo:
pass
print(issubclass(Goo,Foo)) # False
反射(重要)
指的是通过“字符串”对对象或类的属性进行操作
- hasattr:通过字符串判断对象或类是否存在该属性
- getattr:通过字符串,获取对象或类的属性
- setattr:通过字符串,设置对象或类的属性
- delattr:通过字符串,删除对象或类的属性
class People:
country = 'China'
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
p = People('wick',24,'man')
# 普通方式
print('name' in p.__dict) # True
print('country' in People.__dict__) # True
# hasattr
print(hasattr(p,'name')) # True
# 普通方式
print(p.__dict__.get('name')) # wick
print(p.__dict__.get('name1','9')) # 9
# getattr
print(getattr(p,'name','tank')) # wick
print(getattr(p,'name1','tank')) # tank
# 普通方式
p.level = 10
print(p.level) # 10
# setattr
setattr(p,'sal','3.0')
print(hasattr(p,'sal')) # True
# 普通方式
del p.level
print(hasattr(p,'level')) # False
# delattr
delattr(p,'sal')
print(hasattr(p,'sal')) # False
#反射小练习
class Movie:
def input_cmd(self):
print('输出命令:')
while True:
cmd = input('请输入执行方法名:').strip()
if hasattr(self,cmd):
func = getattr(self,cmd)
func()
else:
print('命令错误,请重新输入')
def upload(self):
print('电影开始上传')
def download(self):
print('电影开始下载')
movie_obj = Movie()
movie_obj.input_cmd()
魔法方法(类的内置方法)
凡是在类内部定义,以
__
开头和__
结尾的方法都称之为魔法方法,也叫类的内置方法-
作用:魔法方法会在某些条件成立时触发
__init__
:在调用类时触发__str__
:会在打印对象时触发,必须要返回值,必须是字符串类型__del__
:对象被销毁前执行该方法__getattr__
:会在对象.属性时,属性没有才会触发__setattr__
:会在对象.属性 = 属性时触发__call__
:会在对象被调用时触发__new__
:会在__init__
执行前触发class Foo(object): def __new__(cls, *args, **kwargs): print(cls) return object.__new__(cls) # 真正产生一个空对象 # 若当前类的__new__没有return一个空对象时,则不会触发。 def __init__(self): print('在调用类时触发...') # def __str__(self): # print('会在打印对象时触发...') # # 必须要有一个返回值, 该返回值必须是字符串类型 # return '[1, 2, 3]' def __del__(self): print('对象被销毁前执行该方法...') def __getattr__(self, item): print('会在对象.属性时,“属性没有”的情况下才会触发...') print(item) # 默认返回None, 若想打印属性的结果,必须return一个值 return 111 # 注意: 执行该方法时,外部“对象.属性=属性值”时无效。 def __setattr__(self, key, value): print('会在 “对象.属性 = 属性值” 时触发...') print(key, value) print(type(self)) print(self, 111) self.__dict__[key] = value def __call__(self, *args, **kwargs): print(self) print('调用对象时触发该方法...')
单例模式
-
单例模式指的是单个实例,实例指的是调用类产生的对象
实例化多个对象会产生不同的内存地址,单例可以让所有调用者在调用类产生对象时都指向同一个内存地址,比如打开文件
2 .目的:为了减少内存的只能用
# 要从配置文件中获取三个同样的文件名,会开辟三个空间
# 单例方式1
class File:
__instance = None
@classmethod
def singleton(cls,file_name):
if not cls.__instance:
obj = cls(file_name)
cls.__instance = obj
return cls.__instance
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)
obj1 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
obj2 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
obj3 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
# obj1 = File('jason雨后的小故事.txt')
# obj2 = File('jason雨后的小故事.txt')
# obj3 = File('jason雨后的小故事.txt')
print(obj1)
print(obj2)
print(obj3)
# 单例方式2
class File:
__instance = None
def __new__(cls,*args):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
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)
obj1 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
obj2 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
obj3 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
# obj1 = File('jason雨后的小故事.txt')
# obj2 = File('jason雨后的小故事.txt')
# obj3 = File('jason雨后的小故事.txt')
print(obj1)
print(obj2)
print(obj3)