3)嵌套函数装饰器
上面示例中,都是使用一个装饰器的情况,但实际上,Python 也支持多个装饰器,比如:
@funA
@funB
@funC
def fun():
#...
复制代码
上面程序的执行顺序是里到外,所以它等效于下面这行代码:
fun = funA( funB ( funC (fun) ) )
复制代码
三、类方法修饰
1)实例方法
通常情况下,在类中定义的方法默认都是实例方法。
class Test():
#类构造方法,也属于实例方法
def __init__(self):
self.name = "Test"
self.address = "http://www.study.net"
# 下面定义了一个say实例方法
def say(self):
print("正在调用 say() 实例方法")
if __name__ == "__main__":
t = Test()
# 通过实例对象方法实例方法
t.say()
# 通过类名访问实例对象,但是必须传实例对象名
Test.say(c)
复制代码
2)类方法(@classmethod修饰)
Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls 参数传参。
【温馨提示】和 self 一样,cls 参数的命名也不是规定的(可以随意命名),只是 Python 程序员约定俗称的习惯而已。
和实例方法最大的不同在于,类方法需要使用@classmethod
修饰符进行修饰,例如:
class Test:
#类构造方法,也属于实例方法
def __init__(self):
self.name = "Test"
self.add = "http://www.Test.net"
#下面定义了一个类方法
@classmethod
def info(cls):
print("正在调用类方法",cls)
if __name__ == "__main__":
t = Test()
# 通过对象调用类方法
t.info()
# 通过类名调用类方法,类方法推荐直接通过类名调用
Test.info()
复制代码
注意,如果没有 @classmethod,则 Python 解释器会将 info() 方法认定为实例方法,而不是类方法。
3)静态方法(@staticmethod修饰)
静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。
静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法。
静态方法需要使用@staticmethod
修饰,例如:
class Test:
@staticmethod
def info(name, add):
print(name, add)
if __name__ == "__main__":
c = Test
# 通过对象调用类方法
c.info("测试", 123)
# 通过类名调用类方法(推荐)
Test.info("hello", "world")
复制代码
四、 property() 函数
传统操作类属性的方式比较麻烦,更习惯使用“类对象.属性”这种方式 , Python 中提供了 property() 函数,可以实现在不破坏类封装原则的前提下,让开发者依旧使用“类对象.属性”的方式操作类中的属性。
property() 函数的基本使用格式如下:
属性名=property(fget=None, fset=None, fdel=None, doc=None)
复制代码
fget
参数用于指定获取该属性值的类方法,fset
参数用于指定设置该属性值的方法,fdel
参数用于指定删除该属性值的方法,doc
是一个文档字符串,用于说明此函数的作用。
【注意】在使用 property() 函数时,以上 4 个参数可以仅指定第 1 个、或者前 2 个、或者前 3 个,当前也可以全部指定。也就是说,property() 函数中参数的指定并不是完全随意的。
例如,修改上面的程序,为 name 属性配置 property() 函数:
class CLanguage:
#构造函数
def __init__(self,n):
self.__name = n
#设置 name 属性值的函数
def setname(self,n):
self.__name = n
#访问nema属性值的函数
def getname(self):
return self.__name
#删除name属性值的函数
def delname(self):
self.__name="xxx"
#为name 属性配置 property() 函数
name = property(getname, setname, delname, '指明出处')
#调取说明文档的 2 种方式
#print(CLanguage.name.__doc__)
help(CLanguage.name)
clang = CLanguage("C语言中文网")
#调用 getname() 方法
print(clang.name)
#调用 setname() 方法
clang.name="Python教程"
print(clang.name)
#调用 delname() 方法
del clang.name
print(clang.name)
复制代码
五、hasattr()、getattr()、setattr()函数
1)hasattr()
hasattr()
函数用来判断某个类实例对象是否包含指定名称的属性或方法。该函数的语法格式如下:
hasattr(obj, name)
复制代码
obj
指的是某个类的实例对象,name
表示指定的属性名或方法名。- 同时,该函数会将判断的结果(True 或者 False)作为返回值反馈回来。
示例如下:
class Test001:
def __init__ (self):
self.name = "Test001"
self.add = "http://www.test001.com"
def say(self):
print("我正在学Python")
if __name__ == "__main__":
obj = Test001()
print(hasattr(obj, "name"))
print(hasattr(obj, "add"))
print(hasattr(obj, "say"))
print(hasattr(obj, "fly"))
复制代码
输出结构:
True
True
True
False
复制代码
2)getattr()
getattr()
函数获取某个类实例对象中指定属性的值。没错,和 hasattr() 函数不同,该函数只会从类对象包含的所有属性中进行查找。
getattr() 函数的语法格式如下:
getattr(obj, name[, default])
复制代码
obj
表示指定的类实例对象,name
表示指定的属性名,default
是可选参数,用于设定该函数的默认返回值,即当函数查找失败时,如果不指定 default 参数,则程序将直接报 AttributeError 错误,反之该函数将返回 default 指定的值。
示例如下:
class Test002:
def __init__ (self):
self.name = "Test002"
self.add = "http://www.test002.com"
def say(self):
print("我正在学Python")
if __name__ == "__main__":
obj = Test002()
print(getattr(obj, "name"))
print(getattr(obj, "add"))
print(getattr(obj, "say"))
print(getattr(obj, "display", 'nodisplay'))
复制代码
输出结果:
Test002
http://www.test002.com
<bound method Test002.say of <__main__.Test002 object at 0x00000193F9B98A20>>
nodisplay
复制代码
3)setattr()
setattr()
函数的功能相对比较复杂,它最基础的功能是修改类实例对象中的属性值。其次,它还可以实现为实例对象动态添加属性或者方法。
setattr() 函数的语法格式如下:
setattr(obj, name, value)
复制代码
示例如下:
class Test003:
def __init__ (self):
self.name = "Test003"
self.add = "http://www.test003.com"
def say(self):
print("我正在学Python")
if __name__ == "__main__":
obj = Test003()
print(obj.name)
print(obj.add)
setattr(obj, "name", "Python教程")
setattr(obj, "add", "http://www.test003.net")
print(obj.name)
print(obj.add)
复制代码
输出结果:
Test003
http://www.test003.com
Python教程
http://www.test003.net
复制代码
六、issubclass()和isinstance()函数
Python 提供了如下两个函数来检查类型:
issubclass(cls, class_or_tuple)
:检查 cls 是否为后一个类或元组包含的多个类中任意类的子类。isinstance(obj, class_or_tuple)
:检查 obj 是否为后一个类或元组包含的多个类中任意类的对象。
示例如下:
# 定义一个字符串
hello = "Hello";
# "Hello"是str类的实例,输出True
print('"Hello"是否是str类的实例: ', isinstance(hello, str))
# "Hello"是object类的子类的实例,输出True
print('"Hello"是否是object类的实例: ', isinstance(hello, object))
# str是object类的子类,输出True
print('str是否是object类的子类: ', issubclass(str, object))
# "Hello"不是tuple类及其子类的实例,输出False
print('"Hello"是否是tuple类的实例: ', isinstance(hello, tuple))
# str不是tuple类的子类,输出False
print('str是否是tuple类的子类: ', issubclass(str, tuple))
# 定义一个列表
my_list = [2, 4]
# [2, 4]是list类的实例,输出True
print('[2, 4]是否是list类的实例: ', isinstance(my_list, list))
# [2, 4]是object类的子类的实例,输出True
print('[2, 4]是否是object类及其子类的实例: ', isinstance(my_list, object))
# list是object类的子类,输出True
print('list是否是object类的子类: ', issubclass(list, object))
# [2, 4]不是tuple类及其子类的实例,输出False
print('[2, 4]是否是tuple类及其子类的实例: ', isinstance([2, 4], tuple))
# list不是tuple类的子类,输出False
print('list是否是tuple类的子类: ', issubclass(list, tuple))
复制代码
七、面向切面编程( AOP )
最后
Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
👉Python所有方向的学习路线👈
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
👉Python必备开发工具👈
工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。
👉Python全套学习视频👈
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
👉实战案例👈
学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。
因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。
👉大厂面试真题👈
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!