内建属性与内建函数
内建属性
内建属性指的是在定义完 Python 类后就已存在于该类中的属性,通常这类属性是以双下划线(即__)开头结尾。
在这里,有必要来了解一下 python2 和 python3 不同版本在定义 Python 类的一些区别。在 python2 版本中,无继承父类,则需写上(object),并称之为经典类(或旧式类)
python2
#coding:utf-8
#python2 加object
class AirPlane(object):
pass
python3
#coding:utf-8
#python里默认加object
class AirPlane:
pass
加(object),还是不加? --统一:加上(object) --适配不同 Python 版本 看不同框架!
若要查看上述类的内建属性,则可以使用dir()
函数。
__getattribute__
属性
-魔法方法!
首先,先来理解一下__getattribute__的用法,例如,编写一个树类,有名称–通过外部赋值、高度(内部固定值)这两个属性。
#coding:utf-8
class Tree(object):
#初始化属性
def __init__(self,name):
self.name=name
self.height=10
def __getattribute__(self, item):
"""item指的就是属性访问时的那个属性名,tree.name -->item就是指name"""
print("大树底下好乘凉")
return object.__getattribute__(self,item) #不做任何处理
if __name__=="__main__":
tree=Tree("杨树")
print("树名:",tree.name)
__getattribute__
是属性访问拦截器,就是当这个类的属性被访问时,则会自动调用类的__getattribute__方法。即在上述代码中,当调用实例对象 tree 的 name 属性时,并不会仅直接打印 name 属性值,还会把 name 值作为实参传进__getattribute__方法中且传递给参数item,经过一系列操作(拦截)后,再把name的值进行返回。在Python中,只要定义了继承自 object 的类,则默认存在属性拦截器,只不过是拦截后没有进行任何操作,而是直接返回。因此,在这里,可以在__getattribute__方法内编写代码来实现相关功能,如查看权限( 私有、公有)、打印 log 日志–输出一些文字信息!等操作。
下面通过在__getattribute__方法中进行拦截并打印相关日志信息。–拦截 name 这个属性,若拦截成功,则输出一句话;若不成功,则返回父类的方法。
#coding:utf-8
class Tree(object):
#初始化属性
def __init__(self,name):
self.name=name
self.height=10
def __getattribute__(self, item):
#拦截name这个属性,若拦截成功,则输出一句话(日志);若不成功,则返回父类的方法选择
print("正在调用__getattribute__")
if item=="name":
print("大树")
return "十年树木百年树人" #日志信息
else:
print("这是除name外的其他属性名称:")
return object.__getattribute__(self,item)
if __name__=="__main__":
tree=Tree("杨树")
print("树名:",tree.name)
print(tree.height) #输出树高
另外,需要注意在__getattribute__方法中,最好不要使用 self
来调用某些函数并将值返回__getattribute__方法,因为这样的做法极易导致出现死循环的情况。
#coding:utf-8
class Tree(object):
#初始化属性
def __init__(self,name):
self.name=name
def __getattribute__(self, item):
#调用一个内部方法
print("hello")
return self.show()
def show(self):
return "测试方法show"
if __name__=="__main__":
tree=Tree("杨树")
print("树名:",tree.name)
对于上述程序代码,会发现运行时,一直执行而导致了死循环的类似效果。来分析一下,执行 tree.name 时,先调用__getattribute__方法,发现返回的是self.show(),即 show()的执行结果,接着又要去调用__getattribute__方法,反反复复,没完没了,形成了递归调用且没有退出机制,最终程序就挂了! -->避免:在__getattribute__中不要在使用 self 调用本类中的属性或方法了。
2.内建函数
简单地说,内建函数就是 Python 语法规定已存在的函数,而这类函数通常是包含在 Python 解释器的运行时库中,开发者不必单独书写代码实现它,只需要直接调用即可,而这类函数的实现,是由 Python 解释器厂商完成的。-- 直接调用,不需要导入包而可以直接使用。
若要查看 Python 中有哪些内建函数,则可启动 Python 解释器后,输入 dir(__builtins__)
,即可看到很多默认加载的属性和函数,其中的这些函数就是内建函数,如下:
内建函数数量较多,不宜记忆,且在开发时并不是都会使用到的,若要查看详细使用,则可使用help(function)查看,在这里,仅介绍 sorted(),filter()、map()这几个内置函数。
1.sorted()
查看源码中的信息描述内容。。①直接使用 help()
--参数更加具体;②Ctrl+点击进入源代码。
从上述描述内容中可以知道,sorted()用于返回一个新列表,参数值包含以升序排列的所有可迭代对象。
#coding:utf-8
lists=[1,2,9,7,6,-8,11,-100]
#排序
data=sorted(lists,reverse=False) #从小到大
print(data)
#倒叙
print(sorted(lists,reverse=True))
2.filter()
在 Python 解释器中,内置函数 filter()主要用于对某个序列过滤(序列、过滤器–算法),使用 help()查看 filter()的详细内容。
从上述描述内容中可以知道,filter()函数会对指定序列执行过滤操作,其中参数 1(function)用于接收一个参数–函数名称、(引用),返回布尔值 True 或False,参数 2(iterable)可以是任意可迭代对象,且 filter()函数会对序列参数 iterable 中的每个元素调用 function 函数,最后返回的结果包含调用结果为 True 的元素。
#coding:utf-8
#过滤出所有的数据都大于0
def content_filter(args):
if args>0:
return args
result=filter(content_filter,[1,2,9,7,6,-8,11,-100])
print(result) #迭代器对象
datas=[]
#遍历
for temp in result:
datas.append(temp)
print(datas)
3.map()
函数没有名字:匿名函数。 lambda
能否传入一个匿名函数?
#coding:utf-8
#求两个数的和
get_sum=lambda a,b:a+b
print("两个数的和:",get_sum(12,34))
在 Python 解释器中,内置函数 map()主要用于对指定序列做映射–算法,使用 help()查看详细内容。
想要让序列中的所有元素进行平方处理。 [2,20] -->[4,400]
#coding:utf-8
def get(number):
return number**2
result=map(get,[2,20])
print(result)
for temp in result:
print(temp)
可以直接写成
#coding:utf-8
result=map(lambda a:a**2,[2,20])
print(result)
for temp in result:
print(temp)
3.set集合
可以看出set集合最大特点就是无重复元素值,内容是无序的
在之前的学习过程中–数学中集合(子集、并集…),我们知道,集合与列表、元组等类似,可以存储多个数据,但是这些数据值是不重复的,此外,set 集合对象还支持数学运算中的交集(a&b)、并集(a|b)、差集(a-b)、对称差集(a^b)。
#coding:utf-8
#集合
sets={3.14,23,12,45,"hello"}
data={3.14,12,455,"helloworld",1.72,99}
#交集
print("交集:",sets&data)
#并集
print("并集:",sets|data)
#差集
print("差集:",sets-data)
#对称差集^
print("对称差集:",sets^data)
模块进阶
在 Python 中,有一套非常有用的标准库(standard library),标准库会随着 Python 解释器,一起安装在电脑上。当然,除标准库外,还有很多的其他开源库(即扩展库),它们一起成为了 Python 的组成部分。利用好这些标准库,可以让 Python 编程事半功倍。 --标准库:直接导入模块(Python 本身提供的)即可使用的模块;扩展库:第三方库,自行安装(发布、安装模块),pip
或 pip3 lxml、requests、。。。
1.functools
在 python3 版本中,若要查看 functools 标准库下的属性与函数,则需要先导入 functools
模块,如下:
在这里,我们以 partial()、reduce()、wraps()这几个函数为例进行简要了解。
(1)partial()函数
partial()函数也称为偏函数,它可以把一个函数的某些参数设置为默认值–缺省参数,并用于返回一个新的函数,此时调用新函数会更加简单易用。
*args
# coding:utf-8
import functools
def get_sum(*args):
sum = 0
for element in args:
sum += element
print("所有数之和=", sum)
#在使用到的时候,再导入模块
show=functools.partial(get_sum,100,200)
#调用
show()
#在300这个数之上再对某些数据求和
show(99,34,56)
**kwargs
# coding:utf-8
import functools
def func(**kwargs):
#遍历
for key,value in kwargs.items():
print("%s=%s"%(key,value)) #元组
show=functools.partial(func,name="admin",pwd="123456")
#基础
show(birth="20220401",code="abc")
(2)reduce()函数
在 Python 解释器中,functools 下的 reduce()函数主要用于对参数序列中元素进行累积,使用 help()查看详细内容,如下:
从上述描述内容中可以知道,reduce()函数的参数 1 是一个函数;参数 2(sequence)序列可以是 str、tuple、list等(可迭代对象);参数 3(initial)为固定初始值。reduce()依次从 sequence 中取一个元素,和上一次调用 function()的结果做参数再次调用 function()。第一次调用 function()时,如果提供 initial 参数,会以 sequence 中的第一个元素和initial 作为参数调用function(),否则会以序列sequence中的前两个元素做参数调用function()。注意function()函数不能为 None。
# coding:utf-8
import functools
show=functools.reduce(lambda a,b:a*b,[1,2,3,4,5])
print(show)
result=functools.reduce(lambda a,b:a*b,[1,2,3,4,5],100)
print(result)
上述案例中列表元素前两个相乘后依次从后边的元素在相
(3)wraps()函数
在使用装饰器时,有一些细节需要被注意。例如,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),且在添加装饰器后由于函数名发生了改变,对函数中写的一些文档说明也会有一些影响。
# coding:utf-8
import functools
def welcome(func):
#内部函数
@functools.wraps(func)
def inner():
"""内部函数inner"""
print("欢迎你")
func()
return inner
@welcome
def login():
"""这是登录login"""
print("登录成功")
if __name__=="__main__":
login()
help(login)
仔细观察上述运行结果,很容易发现,未显示出 login()中的文档说明。此时,若想要完全输出文档说明的内容,就可以使用 wraps()函数了,只需要在 inner()外添加 wraps()这个装饰器来即可显示正确的文档说明。
2.json模块
–json 是什么:数据格式!特殊的字符串,有特定的格式。–Python 中的 dict
JSON 是一种轻量级数据交换格式,通常用于在 Web 客户端和服务器数据交换,即把字符串类型的数据转换成 Python 基本数据类型或将 Python 基本数据类型转换成字符串类型,JSON 数据格式显示样式如下:
对象(字典):{ }
数组(列表):[ ] -->可以存放多个对象。
区别:json 的所有 key 都是字符串。
对于 json 模块下的常用函数如下:
loads
(obj) -----将字符串序列化成 Python 的基本数据类型,注意单引号与双引号。
dumps
(obj) ----将 Python 的基本数据类型序列化成字符串。
load
(obj) 读取文件中的字符串,序列化成 Python 的基本数据类型。
dump
(obj) 将 Python 的基本数据类型序列化成字符串并写入到文件中。
案例 1:把 json 字符串转换为 Python 数据类型 loads()
# coding:utf-8
import json
# json_strs = "{\"\":\"\"}" # 转义
json_strs="{\"name\":\"admin123\",\"password\":\"123456\"}" # 转义
# json_strs = "{'name':'admin123','password':'123456'}" # 单引号 -->注意:使用单引号时,json 模块识别时会出问题
print(json_strs)
print(type(json_strs))
#把json转换为python数据类型 ---字典
result=json.loads(json_strs)
print(result)
print(type(result))
案例 2:把 Python 数据类型转换为 json
# coding:utf-8
import json
#python数据类型转换--json
datas={"name":"admin123","password":"123456"}
# print(type(datas)) 字典
result=json.dumps(datas)
print(result)
print(type(result))
print("-"*20)
#json---->python数据类型结构
source=json.loads(result)
print(source) #可以转换成功
案例 3:Python 的基本数据类型序列化成字符串 类文件对象。open()
# coding:utf-8
import json
#python数据
datas={"name":"admin","password":"123456"}
fs=open("data.json","w")
#转换为json、存入文件中
json.dump(datas,fs)
fs.close()
print("存入成功")
案例 4:读取文件中的字符串,序列化成 Python 的基本数据类型
# coding:utf-8
import json
result=json.load(open("data.json","r"))
print(result)
接下来,稍微了解一下 JSON 数据格式与 Python 解码后数据类型匹配,如下:
常用拓展库