开篇絮絮念
前面咱们已经和面向对象又进一步深入了关系,接下来咱们就该用细节来打动她,把面向对象变成我们的囊中之物,桀桀桀桀桀~~
面向对象之静态方法、实例方法和类方法
(一)实例方法
声明在类型内部的普通方法,第一个参数是当前对象本身,实例方法在执行过程中可以访问当前对象的所有属性与方法,当前类型的属性和方法;实例方法在使用过程中只能被对象的引用变量执行调用。
class User:
"""用户类"""
max_age = 99
def __init__(self, username):
self.username = username
def show_info(self):
"""实例方法,可以访问当前对象和类型的所有属性与方法"""
print(f"我的用户名是{self.username},最大年龄是{self.max_age}"
me = User("B+Tree")
me.show_info() # 我的用户名是B+Tree,最大年龄是99
(二)类方法
类方法是声明在类型内部,使用装饰器@classmethod声明的方法,第一个参数是当前类型本身,约定俗成使用cls表示;类方法只能访问当前类型的类属性,不能访问任何对象的实例属性;类方法能被当前类型调用,也能被实例对象调用。
class User:
"""用户类"""
mas_age = 99
def __init__(self, username):
self.username = username
def show_info(self):
print(f"我的用户名是{self.username},最大年龄是{self.max_age}"
@classmethod
def show_age(cls):
"""类方法只能访问类属性"""
print(f"我的最大年龄是{cls.max_age}")
me = User("B+Tree")
me.show_info()
User.show_age() # 我的最大年龄是99
(三)静态方法
静态方法本质上是被同一管理在类型中的函数,在类型中使用@staticmethod装饰器声明;静态方法时独立的方法,不能访问类型的任何信息;静态方法可以被类型名称直接调用,也可以被对象的引用变量调用执行
import time
class User:
max_age = 99
def __init__(self, username):
self.username = username
@classmethod
def show_age(cls):
"""类方法只能访问类属性"""
print(f"我的最大年龄是{cls.max_age}")
@staticmethod
def system_exit():
print("正在退出系统...")
time.sleep(2)
print("退出系统")
exit(0)
me = User("B+Tree")
me.system_exit()
方法特性总结
方法类型 | 功能描述 | 访问类属性 | 访问实例属性 |
---|---|---|---|
实例方法 | 对象独立的方法,不同对象 之间相互隔离,互不影响 用于完成和当前对象 有关的功能 | 能 | 能 |
类方法 | 所有对象的公共方法,可以 可以访问类属性完成和属性 相关的功能 | 能 | 不能 |
静态方法 | 所有对象的公共方法, 用于执行独立的功能 | 不能 | 不能 |
方法声明区分办法(根据可访问的属性来区分):
①当类型中的方法需要访问实例属性时,该方法就是实例方法
②当类型中的方法只需要访问类属性时,该方法就是类方法
③当类型中的方法既不需要访问类属性,也不需要访问实例属性时,该方法就是静态方法。
魔法方法补漏
dict()方法:获取对象的所有属性值,包括私有属性,并以字典形式返回结果。
import time
class User:
max_age = 99
def __init__(self, username, age, gender):
self.username = username
self.age = age
self.gender = gender
@classmethod
def show_age(cls):
"""类方法只能访问类属性"""
print(f"我的最大年龄是{cls.max_age}")
@staticmethod
def system_exit():
print("正在退出系统...")
time.sleep(2)
print("退出系统")
exit(0)
me = User("B+Tree", 18, "男")
ret = me.__dict__
print(ret) # {'username': 'B+Tree', 'age': 18, 'gender': '男'}
反射方法
(一)什么是反射
反射本质上描述的是反射调用,本意是不直接操作目标函数或者目标属性,而是在运行过程中获取到给定目标属性和目标方法的字符串名称,通过语义同像性的语法动态获取程序内部状态,进而操作目标对象的属性和目标方法的过程。
反射是编程语言中的一种高级操作方式,在很多特定场景有不同的应用;如容错操作提高开发效率,在完全按照项目规范的详细设计文档进行项目开发过程中,不能保证当前模块的依赖是否研发完成,为了保证程序完整性的同时保障已开发功能的完善,使用反射来完成容错开发。
(二)常见的反射方法
反射放啊是python解释器在启动程序时就内建加载的方法,可以通过反射方法在程序运行期间获取程序在内存中的状态,并获取目标对象的实例属性和实例方法并执行。
hasattr(obj, name);判断是否包含名称为name的属性
setattr(obj, name, value):给名称为name的属性设置value数据
getattr(obj, name):获取名称为name的属性具体数据
delatter(obj, name):删除名称为name的属性
** 上述的name需要是字符串的形式
class User:
max_age = 99
print(hasattr(User, "max_age")) # 判断是否包含名称为"max_age"的属性
print(getattr(User, "max_age")) # 获取名称为"max_age"的属性具体数据
setattr(User, "max_age", 199) # 给名称为"max_age"的属性设置数据为199
print(getattr(User, "max_age"))
delattr(User, "max_age") # 删除名称为"max_age"的属性
print(hasattr(User, "max_age"))
面向对象扩展之单例模式
简单来说单例模式就是程序中只允许出现单个的对象,程序中不存在其他与该对象相同类型的对象。实现思路就是让在创建对象时进行条件判断,若存在该类型的对象则返回已创建的对象;若不存在该类型对象即第一次创建时,才创建新对象。
代码实现如下:
class Shopping:
instance = None # 记录创建的对象,None说明是第一次创建对象
def __new__(cls, *args, **kwargs):
# 第一次调用new方法,创建对象并记录
# 第2-n次调用new方式时,不创建对象,而是直接放回记录的对象
# 判断是否是第一次创建对象
if cls.instance is None:
cls.instance = object.__new__(cls)
return cls.instance
可以看到两个对象的内存一致,即表示创建的两个对象实际都是同一个,满足单例模式需求。