Python中常用的73个内置函数

Python中常用的73个内置函数

【一】什么是内置函数?

  • 内置函数就是Python给你提供的, 拿来直接用的函数,比如print,input等。

  • 截止到python版本3.6.2 ,一共提供了68个内置函数,具体如下

Built-in Functions
Aabs()aiter()all()any()anext()ascii()
Bbin()bool()breakpoint()bytearray()bytes()
Ccallable()chr()classmethod()compile()complex()
Ddelattr()dict()dir()divmod()
Eenumerate()eval()exec()
Ffilter()float()format()frozenset()
Ggetattr()globals()
Hhasattr()hash()help()hex()
Iid()input()int()isinstance()issubclass()iter()
Llen()list()locals()
Mmap()max()memoryview()min()
Nnext()
Oobject()oct()open()ord()
Ppow()print()property()
Rrange()repr()reversed()round()
Sset()setattr()slice()sorted()staticmethod()str()sum()super()
Ttuple()type()
Vvars()
Zzip()
___import__()
  • 和数字相关

    • \1. 数据类型
    • \2. 进制转换
    • \3. 数学运算
  • 和数据结构相关

    • \1. 序列
    • \2. 数据集合
    • \3. 相关内置函数
  • 和作用域相关

  • 和迭代器生成器相关

  • 字符串类型代码的执行

  • 输入输出

  • 内存相关

  • 文件操作相关

  • 模块相关

  • 帮 助

  • 调用相关

  • 查看内置属性

【二】和数据结构相关的内置函数之序列(36)

【1】数据类型之间的转换(4)

  • bool: 布尔类型(True / False)
  • int : 整型(整数)
  • float : 浮点型(小数)
  • complex : 复数

【2】进制转换(3)

  • bin() 将给的参数转换成二进制

    print(bin(10))  # 二进制:0b1010
    
  • oct() 将给的参数转换成八进制

    print(hex(10))  # 十六进制:0xa
    
  • hex() 将给的参数转换成十六进制

    print(oct(10))  # 八进制:0o12
    

【3】数学运算(7)

  • abs() 返回绝对值

    print(abs(-2))  # 绝对值:2
    
  • divmod() 返回商和余数

    print(divmod(20,3)) # 求商和余数:(6,2)
    
  • round() 四舍五入

    print(round(4.50))   # 五舍六入:4
    print(round(4.51))   #5
    
  • pow(a, b) 求a的b次幂, 如果有三个参数. 则求完次幂后对第三个数取余

    print(pow(10,2,3))  # 如果给了第三个参数. 表示最后取余:1
    
  • sum() 求和

    print(sum([1,2,3,4,5,6,7,8,9,10]))  # 求和:55
    
  • min() 求最小值

    print(min(5,3,9,12,7,2))  #求最小值:2
    
  • max() 求最大值

    print(max(7,3,15,9,4,13))  #求最大值:15
    

【4】数据结构相关(22)

(1)序列(12)
(1.1)列表和元祖(2)
  • list() 将一个可迭代对象转换成列表

    print(list((1,2,3,4,5,6)))  #[1, 2, 3, 4, 5, 6]
    
  • tuple() 将一个可迭代对象转换成元组

    print(tuple([1,2,3,4,5,6]))  #(1, 2, 3, 4, 5, 6)
    
(1.2)内置函数(2)
  • reversed() 将一个序列翻转, 返回翻转序列的迭代器

    lst = "你好啊"
    it = reversed(lst)   # 不会改变原列表. 返回一个迭代器, 设计上的一个规则
    print(list(it))  #['啊', '好', '你']
    
  • slice() 列表的切片

    lst = [1, 2, 3, 4, 5, 6, 7]
    print(lst[1:3:1])  #[2,3]
    s = slice(1, 3, 1)  #  切片用的
    print(lst[s])  #[2,3]
    
(1.3)字符串(8)
  • str() 将数据转化成字符串

    print(str(123)+'456')  #123456
    
  • format() 与具体数据相关, 用于计算各种小数, 精算等.

    s = "hello world!"
    print(format(s, "^20"))  #居  中
    #     hello world!    
    print(format(s, "<20"))  #左对齐
    # hello world!        
    print(format(s, ">20"))  #右对齐
    #         hello world!
    
    
    print(format(3, 'b' ))    # 二进制:11
    print(format(97, 'c' ))   # 转换成unicode字符:a
    print(format(11, 'd' ))   # ⼗进制:11
    print(format(11, 'o' ))   # 八进制:13 
    print(format(11, 'x' ))   # 十六进制(⼩写字母):b
    print(format(11, 'X' ))   # 十六进制(大写字母):B
    print(format(11, 'n' ))   # 和d⼀样:11
    print(format(11))         # 和d⼀样:11
    print(format(123456789, 'e' ))      # 科学计数法. 默认保留6位小数:1.234568e+08
    print(format(123456789, '0.2e' ))   # 科学计数法. 保留2位小数(小写):1.23e+08
    print(format(123456789, '0.2E' ))   # 科学计数法. 保留2位小数(大写):1.23E+08
    print(format(1.23456789, 'f' ))     # 小数点计数法. 保留6位小数:1.234568
    print(format(1.23456789, '0.2f' ))  # 小数点计数法. 保留2位小数:1.23
    print(format(1.23456789, '0.10f'))  # 小数点计数法. 保留10位小数:1.2345678900
    print(format(1.23456789e+3, 'F'))   # 小数点计数法. 很大的时候输出INF:1234.567890
    
  • bytes() 把字符串转化成bytes类型

    bs = bytes("今天吃饭了吗", encoding="utf-8")
    print(bs) 
    # b'\xe4\xbb\x8a\xe5\xa4\xa9\xe5\x90\x83\xe9\xa5\xad\xe4\xba\x86\xe5\x90\x97'
    
  • bytearray()

    • 返回一个新字节数组. 这个数字的元素是可变的, 并且每个元素的值得范围是[0,256)

      ret = bytearray("alex" ,encoding ='utf-8')
      print(ret[0])  #97
      print(ret)  #bytearray(b'alex')
      ret[0] = 65  #把65的位置A赋值给ret[0]
      print(str(ret))  #bytearray(b'Alex')
      
  • ord() 输入字符找带字符编码的位置

    print(ord('a'))  # 字母a在编码表中的码位:97
    print(ord('中'))  # '中'字在编码表中的位置:20013
    
  • chr() 输入位置数字找出对应的字符

    print(chr(65))  # 已知码位,求字符是什么:A
    print(chr(19999))  #丟
    
  • ascii() 是ascii码中的返回该值 不是就返回u

    for i in range(65536):  #打印出0到65535的字符
        print(chr(i), end=" ")
    
    print(ascii("@"))  #'@'
    
  • repr() 返回一个对象的string形式

    s = "今天\n吃了%s顿\t饭" % 3
    print(s)#今天# 吃了3顿    饭
    print(repr(s))   # 原样输出,过滤掉转义字符 \n \t \r 不管百分号%
    #'今天\n吃了3顿\t饭'
    
(2)数据集合(3)
  • 字典:dict 创建一个字典
  • 集合:set 创建一个集合

frozenset() 创建一个冻结的集合,冻结的集合不能进行添加和删除操作。

(3)相关内置函数(8)
  • len() 返回一个对象中的元素的个数

  • sorted() 对可迭代对象进行排序操作 (lamda)

    lst = [5,7,6,12,1,13,9,18,5]
    lst.sort()  # sort是list里面的一个方法
    print(lst)  #[1, 5, 5, 6, 7, 9, 12, 13, 18]
    
    ll = sorted(lst) # 内置函数. 返回给你一个新列表  新列表是被排序的
    print(ll)  #[1, 5, 5, 6, 7, 9, 12, 13, 18]
    
    l2 = sorted(lst,reverse=True)  #倒序
    print(l2)  #[18, 13, 12, 9, 7, 6, 5, 5, 1]
    

语法:sorted(Iterable, key=函数(排序规则), reverse=False)

  • Iterable: 可迭代对象
  • key: 排序规则(排序函数), 在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数. 根据函数运算的结果进行排序
  • reverse: 是否是倒叙. True: 倒叙, False: 正序
#根据字符串长度给列表排序
lst = ['one', 'two', 'three', 'four', 'five', 'six']
def f(s):
    return len(s)
l1 = sorted(lst, key=f, )
print(l1)  #['one', 'two', 'six', 'four', 'five', 'three']
  • enumerate() 获取集合的枚举对象

    lst = ['one','two','three','four','five']
    for index, el in enumerate(lst,1):    # 把索引和元素一起获取,索引默认从0开始. 可以更改
        print(index)
        print(el)
    # 1
    # one
    # 2
    # two
    # 3
    # three
    # 4
    # four
    # 5
    # five
    
  • all() 可迭代对象中全部是True, 结果才是True

    print(all([1,'hello',True,9]))  #True
    
  • any() 可迭代对象中有一个是True, 结果就是True

    print(any([0,0,0,False,1,'good']))  #True
    
  • zip() 函数

    • 用于将可迭代的对象作为参数
    • 将对象中对应的元素打包成一个元组
    • 然后返回由这些元组组成的列表.

如果各个迭代器的元素个数不一致, 则返回列表长度与最短的对象相同

lst1 = [1, 2, 3, 4, 5, 6]
lst2 = ['醉乡民谣', '驴得水', '放牛班的春天', '美丽人生', '辩护人', '被嫌弃的松子的一生']
lst3 = ['美国', '中国', '法国', '意大利', '韩国', '日本']
print(zip(lst1, lst1, lst3))  #<zip object at 0x00000256CA6C7A88>
for el in zip(lst1, lst2, lst3):
    print(el)
# (1, '醉乡民谣', '美国')
# (2, '驴得水', '中国')
# (3, '放牛班的春天', '法国')
# (4, '美丽人生', '意大利')
# (5, '辩护人', '韩国')
# (6, '被嫌弃的松子的一生', '日本')
  • filter() 过滤 (lamda)

语法:fiter(function. Iterable)

function: 用来筛选的函数.

​ 在filter中会自动的把iterable中的元素传递给function.

​ 然后根据function返回的True或者False来判断是否保留留此项数据

Iterable: 可迭代对象

def func(i):    # 判断奇数
    return i % 2 == 1
    lst = [1,2,3,4,5,6,7,8,9]
l1 = filter(func, lst)  #l1是迭代器
print(l1)  #<filter object at 0x000001CE3CA98AC8>
print(list(l1))  #[1, 3, 5, 7, 9]
  • map() 会根据提供的函数对指定序列列做映射(lamda)

语法 : map(function, iterable)

可以对可迭代对象中的每一个元素进行映射. 分别去执行 function

def f(i):    
  return i
  lst = [1,2,3,4,5,6,7,]
it = map(f, lst) # 把可迭代对象中的每一个元素传递给前面的函数进行处理. 处理的结果会返回成迭代器print(list(it))  #[1, 2, 3, 4, 5, 6, 7]

【三】和作用域相关(2)

  • locals() 返回当前作用域中的名字
  • globals() 返回全局作用域中的名字
def func():
    a = 10
    print(locals())  # 当前作用域中的内容
    print(globals())  # 全局作用域中的内容
    print("今天内容很多")
func()
# {'a': 10}
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': 
# <_frozen_importlib_external.SourceFileLoader object at 0x0000026F8D566080>, 
# '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' 
# (built-in)>, '__file__': 'D:/pycharm/练习/week03/new14.py', '__cached__': None,
#  'func': <function func at 0x0000026F8D6B97B8>}
# 今天内容很多

【四】和迭代器生成器相关(3)

  • range() 生成数据
  • next()
    • 迭代器向下执行一次, 内部实际使用了__ next__()方法返回迭代器的下一个项目
  • iter()
    • 获取迭代器, 内部实际使用的是__ iter__()方法来获取迭代器
for i in range(15,-1,-5):
    print(i)
# 15
# 10
# 5
# 0
lst = [1,2,3,4,5]
it = iter(lst)  #  __iter__()获得迭代器
print(it.__next__())  #1
print(next(it)) #2  __next__()  
print(next(it))  #3
print(next(it))  #4

【五】字符串类型代码的执行(3)

  • eval() 执行字符串类型的代码. 并返回最终结果

    s1 = input("请输入a+b:")  #输入:8+9
    print(eval(s1))  # 17 可以动态的执行代码. 代码必须有返回值
    
  • exec() 执行字符串类型的代码

    s2 = "for i in range(5): print(i)"
    a = exec(s2) # exec 执行代码不返回任何内容
    
    # 0
    # 1
    # 2
    # 3
    # 4
    print(a)  #None
    
    # 动态执行代码
    exec("""
    def func():
        print(" 我是周杰伦")
    """ )
    func()  #我是周杰伦
    
  • compile() 将字符串类型的代码编码. 代码对象能够通过exec语句来执行或者eval()进行求值

    code1 = "for i in range(3): print(i)"
    com = compile(code1, "", mode="exec")   # compile并不会执行你的代码.只是编译
    exec(com)   # 执行编译的结果
    # 0
    # 1
    # 2
    
    code2 = "5+6+7"
    com2 = compile(code2, "", mode="eval")
    print(eval(com2))  # 18
    
    code3 = "name = input('请输入你的名字:')"  #输入:hello
    com3 = compile(code3, "", mode="single")
    exec(com3)
    print(name)  #hello
    

【六】输入输出(2)

  • print() : 打印输出

    print("hello", "world", sep="*", end="@") 
    # sep:打印出的内容用什么连接
    # end:以什么为结尾
    # hello*world@
    
  • input() : 获取用户输出的内容

【七】内存相关(3)

  • hash() :
    • 获取到对象的哈希值(int, str, bool, tuple).
  • hash算法:
    • (1) 目的是唯一性
    • (2) dict 查找效率非常高
  • hash表:
    • 用空间换的时间 比较耗费内存
s = 'alex'
print(hash(s))  #-168324845050430382
lst = [1, 2, 3, 4, 5]
print(hash(lst))  #报错,列表是不可哈希的
  id() :  获取到对象的内存地址
s = 'alex'
print(id(s))  #2278345368944

【八】文件操作相关(1)

  • open() : 用于打开一个文件, 创建一个文件句柄

    f = open('file',mode='r',encoding='utf-8')
    f.read()
    f.close()
    

【九】模块相关(1)

  • __ import__() : 用于动态加载类和函数

    # 让用户输入一个要导入的模块
    import os
    name = input("请输入你要导入的模块:")
    __import__(name)    # 可以动态导入模块
    

【十】帮助(1)

  • help() : 函数用于查看函数或模块用途的详细说明

    print(help(str))  #查看字符串的用途
    

【十一】调度相关(1)

  • callable() : 用于检查一个对象是否是可调用的. 如果返回True, object有可能调用失败, 但如果返回False. 那调用绝对不会成功

    a = 10
    print(callable(a))  #False  变量a不能被调用
    #
    def f():
        print("hello")
        print(callable(f))   # True 函数是可以被调用的
    

【十二】查看内置属性(1)

  • dir() :

    • 查看对象的内置属性

    • 访问的是对象中的 __dir__() 方法

      print(dir(tuple))  #查看元组的方法
      

【十三】aiter()函数(1) - py3.10+

  • 语法:

    aiter(async_iterable)
    
  • 其中 async_iterable 是一个异步可迭代对象,相当于调用 x.aiter()。

注意:与 iter() 不同,aiter() 没有两个参数的版本。

  • aiter() 和 anext() 调用对象的 aiter() 和 anext()
  • 它们本质上是 iter() 和 next() 的异步等价物。 在大多数情况下,很少需要直接使用新的内置函数, 我们可以直接用async for代替。 async for 循环已经隐式调用了类的 aiteranext 方法。

【1】应用

  • 如果您正在编写的代码以某种方式与异步迭代器交互,那么您只需要显式使用 aiter 和 anext,而这种方式不被 async for 循环直接支持。
  • 例如,这是一个异步生成器,它从给定的可迭代对象中产生成对的值:
async def pairwise(aiterable, default=None):
    # 获取对迭代器的引用
    ait = aiter(aiterable)
    # 得到一个额外的值,产生一个 2 元素元组
    async for x in ait:
        yield x, await anext(ait, default)
  • 如果您在 main 函数中循环使用 pairwise(AIter(10)),您会发现它现在打印数字元组
  • 例如 finally (0, 1)。
    • 在每个元组之前
    • 您将看到由迭代器类打印的两组开始行和结束行
    • 一组用于最终出现在配对结果中的每个值。

【2】示例

import asyncio

async def numbers(nums):
    for i in range(nums):
        yield i
        await asyncio.sleep(0.5)


# 隐式使用
[i async for i in numbers(10) if i % 2 == 0]
# 显式使用
[i async for i in aiter(numbers(10)) if i % 2 == 0]
# [0, 2, 4, 6, 8]

a = aiter(numbers(10))
dir(a)
'''
['__aiter__',
 '__anext__',
 '__class__',
...
'''
  • 在上面的代码中,numbers() 函数是一个异步生成器,它为异步列表理解生成值。

【十四】anext()函数(1) - py3.10+

【1】作用

  • anext() 是 Python 3.10 版本中的一个新函数。
  • 它在等待时从异步迭代器返回下一项
    • 如果给定并且迭代器已用尽
      • 则返回默认值。
  • 这是 next() 内置的异步变体,行为类似。

【2】语法

awaitable anext(async_iterator[, default])
  • 其中 async_iterator 是一个异步迭代器。
    • 它接受一个可选参数,当迭代器耗尽时返回。
  • 当进入 await 状态时
    • 从给定异步迭代器(asynchronous iterator)返回下一数据项
    • 迭代完毕则返回 default。
  • 这是内置函数 next() 的异步版本,类似于调用 async_iterator 的 anext() 方法,返回一个 awaitable,等待返回迭代器的下一个值。
    • 若有给出 default
      • 则在迭代完毕后会返回给出的值
      • 否则会触发 StopAsyncIteration。

【3】示例

import asyncio

class CustomAsyncIter:
    def __init__(self):
        self.iterator = iter(['A', 'B'])
    def __aiter__(self):
        return self
    async def __anext__(self):
        try:
            x = next(self.iterator)
        except StopIteration:
            raise StopAsyncIteration from None
        await asyncio.sleep(1)
        return x

async def main1():
    iter1 = CustomAsyncIter()
    print(await anext(iter1))       # Prints 'A'
    print(await anext(iter1))       # Prints 'B'
    print(await anext(iter1))       # Raises StopAsyncIteration

async def main2():
    iter1 = CustomAsyncIter()
    print('Before')                 # Prints 'Before'
    print(await anext(iter1, 'Z'))  # Silently terminates the script!!!
    print('After')                  # This never gets executed

asyncio.run(main1())
'''
A
B
raise StopAsyncIteration
'''

asyncio.run(main2())
'''
Before
A
After
'''

【十五】breakpoint()函数(1) - 3.7+

【1】作用

  • Python 3.7添加了breakpoint(),此函数将您放入调用站点的调试器中。
  • 具体来说,它调用sys.breakpointhook(),直接传递args和kws。
  • 默认情况下,sys.breakpointhook()调用pdb.set_trace(),不需要参数。
    • 在这种情况下,它纯粹是一个方便的函数,因此您不必显式地导入pdb或键入足够多的代码来进入调试器。
    • 但是,sys.breakpointhook()可以设置为其他函数,breakpoint()将自动调用该函数,允许您进入所选的调试器。

【2】语法

breakpoint(*args, **kws)
  • 参数介绍:
    • *args, **kws---不定长参数
  • 返回值:
    • 下面例子展示 breakpoint()函数使用方法

【3】示例

# 以前
foo()
import pdb; pdb.set_trace()
bar()
# 现在
foo()
breakpoint()
bar()
  • *args, **kws --- 不定长参数区别
def f(arg,*args,**kwargs):
    print(arg,args,kwargs)
f(1,2,4,5,a=1,b=2)

# 1 (2, 4, 5) {'a': 1, 'b': 2}

【十六】classmethod()函数(1)

【1】作用

  • 将方法转换为类方法。
    • 类方法将类作为隐式第一个参数接收,就像实例方法接收实例一样。
  • 类方法可以在类(如c.f())上调用,也可以在实例(如c().f())上调用。
    • 除了类之外,实例被忽略。
    • 如果为派生类调用了类方法,则派生类对象将作为隐含的第一个参数传递。
    • 类方法不同于C++或Java静态方法。
  • 也就是说,classmethod修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象。

【2】语法

class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ...

【3】示例

  • 返回值:
    • 返回函数的类方法
    • 下面例子展示classmethod()函数函数使用方法
class B(object):
    num = 10
    def func1(self):
        print('self')
    @classmethod
    def func2(cls):
        print('func2')
        print(cls.num)
        cls().func1()
B.func2()  # 不需要实例化

# func2
# 10
# self

【十七】Python中的反射机制(4)

【1】什么是反射?

  • 反射指在程序运行过程中可以动态获取对象的信息。
    • 是通过字符串的形式,导入模块;
    • 通过字符串的形式,去模块寻找指定函数,并执行。
    • 利用字符串的形式去对象中操作成员,一种基于字符串的驱动

【2】Python反射中的内置函数

(1)getattr()
  • getattr():
    • 用于获取对象中的属性
    • 但是其不能获取私有变量也就是最前面带__的属性或方法

getattr(object,name,default)其有三个参数

  1. object:对象
  2. name:对象中的属性值
  3. default:可选 该对象中不存在该属性的时候的返回值。
  • 示例
class B:
    def __init__(self):
        self.name = 'Bb'
        self.age = 40

    def add(self):
        print('B')


if __name__ == '__main__':
    b = B()
    print(getattr(b, 'name', 'not found'))  # 输出:Bb
    print(getattr(b, 'cc', 'not found'))  # 输出:not found
    func = getattr(b,'add',None)
    print(func)  # 输出:<bound method B.add of <__main__.B object at 0x00000248C7F48648>>
    func()  # 输出:B
(2)hasattr()
  • hasattr(object,name)

    • 该函数用于检测对象(object)中是否含有name (指的是某个属性名而并不是指name) 这个属性
      • 其中object是对象
      • name是指需要检查该对象中是否存在的属性的名称。
  • 示例

class B:
    def __init__(self):
        self.name = 'Bb'
        self.age = 40

    def add(self):
        print('B')


if __name__ == '__main__':
    b = B()
    print(hasattr(b, 'ccc')) # False
    print(hasattr(b, 'add')) # True
(3)setattr()
  • setattr(object,name,value)

    • 是指给某个对象某个属性设置指定的值
      • object是对象
      • name是对象中的属性名
      • value是你想要设的值。
    • 其中三个参数都是必须的填的。
  • 该函数可以给对象增加新的属性并且可以将对象中的方法改变。

  • 示例

class B:
    def __init__(self):
        self.name = 'Bb'
        self.age = 40

    def add(self):
        print('B')


if __name__ == '__main__':
    b = B()
    print(b.age)  # 40
    setattr(b,'age',50)
    print(b.age)  # 50

    def cc():
        print('i am changed')
	b.add() # B
    setattr(b,'add',cc)
    b.add() # i am changed
    # print(dir(b))
(4)delattr()
  • delattr(object,name)

    • 指删除对象中的指定属性
      • 其中object是对象
      • name是对象中的属性名。
  • 示例

class B:
    def __init__(self):
        self.name = 'Bb'
        self.age = 40

    def add(self):
        print('B')


if __name__ == '__main__':
    b = B()
    print(dir(b))  # [,'add', 'age', 'name'] dir()函数会输出一大堆,在这里我把输出的一些属性名直接删除了
    print(hasattr(b,'age'))  # True
    delattr(b,'age')
    print(dir(b))  # [,'add', 'name']
    print(hasattr(b,'age'))  # False

我在这里再补充说明下dir() 这个函数: dir()不带变量时候用于获取当前范围内的变量、方法和定义的类型列表;带参数时返回参数的属性、方法列表。

dir(object) object:对象、变量、类型

  • 以上就是python反射中的四个内置函数。

【3】Python反射的应用

  • 反射的一个应用就是web框架中的url路由
    • 用户通过输入url路由就可以定位到views视图中的函数
    • 这里面主要应用了getattr() 这个函数(一个用于获取views视图中对应函数
      • 如果没有就返回你设定的值以此判断是否可以往下执行。

【十八】id()函数 -- 判断内存空间地址(1)

【1】作用

  • 在Python中,id()函数用于返回一个对象的唯一标识符。
  • 这个标识符是一个整数,代表了该对象在内存中的地址。
  • 换句话说,每个对象都有一个唯一的标识符,即使它们的值相同也是如此。

【2】语法

id(object)
# 其中,object是要返回标识符的对象。

【3】示例

a = 5
b = 5
print("a的标识符为:", id(a))
print("b的标识符为:", id(b))

# a的标识符为: 140707288191088
# b的标识符为: 140707288191088

可以看到,即使a和b的值相同,它们的标识符也相同,这是因为它们指向的是同一个内存地址。

【十九】isinstance()函数 -- 检查类型(2)

【1】作用

  • 这个函数有点类似type函数的定义

    • type判断 函数类型是什么
    • 而isinstance是 通过判断对象是否是已知的类型
  • 但是isinstance比type高级一些(功能上的差异)

  • 具体差异:

    • type()
      • 不考虑继承关系(子类不是父类类型)
    • isinstance()
      • 考虑继承关系(子类是父类类型)

【2】语法

  • 官方文档
def isinstance(x, A_tuple): # real signature unknown; restored from __doc__
    """
    Return whether an object is an instance of a class or of a subclass thereof.
    
    A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to
    check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)
    or ...`` etc.
    """
    pass

isinstance(object, classinfo)
object :实例对象
classinfo :类型可以是 直接或间接类名、基本类型以及元组

  • 说人话

    tmp = 2
    isinstance(tmp,int)      # 结果返回 True
    isinstance(tmp,str)      # 结果返回 False
    
    tmp2 = {"a":19}          #定义一个dict类型的变量
    isinstance(tmp2,dict)    # 结果返True
    
    
    • 通过以上实例,我们可以看到isinstance()基本用法为:
    isinstance(object,classinfo)
    

其中参数:

  • object : 实例对象。
  • classinfo : 可以是直接或者间接类名、基本类型或者由它们组成的元组。

返回值:

​ 如果对象(object)的类型与参数(classinfo)的类型相同则返回 True,否则返回 False。

【3】函数版用法

  • 基础版
a = 10086
isinstance (a,int)  # true

isinstance (a,str) # false

isinstance (a,(str,int,list))    
# 只要满足元组类型中的其中一个即可,答案是满足,所以为true
  • 进阶版
s = () # 定义一个元组类型
isinstance(s,tuple) # true
isinstance(s,list) # false

s1 = [] # 定义一个列表类型
isinstance(s1,list) # true

s2 = {} # 定义一个字典类型
isinstance(s2,dict) # true

# 混合类型判断,通过for索引取值判断
isinstance(s,(tuple,list,dict)) 

【二十】issubclass()函数 -- 检查类型(1)

【1】作用

  • 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))
  • 通过上面程序可以看出
    • issubclass() 和 isinstance() 两个函数的用法差不多
    • 区别只是
      • issubclass() 的第一个参数是类名
      • 而 isinstance() 的第一个参数是变量
    • 这也与两个函数的意义对应:
      • issubclass 用于判断是否为子类,
      • 而 isinstance() 用于判断是否为该类或子类的实例。
issubclass() 和 isinstance() 两个函数的第二个参数都可使用元组。例如如下代码:
data = (20, 'fkit')
print('data是否为列表或元组: ', isinstance(data, (list, tuple))) # True
# str不是list或者tuple的子类,输出False
print('str是否为list或tuple的子类: ', issubclass(str, (list, tuple)))
# str是list或tuple或object的子类,输出True
print('str是否为list或tuple或object的子类 ', issubclass(str, (list, tuple, object)))

【二十一】memoryview() 函数(1)

【1】作用

  • memoryview() 函数返回给定参数的内存查看对象(memory view)。
  • 所谓内存查看对象
    • 是指对支持缓冲区协议的数据进行包装
    • 在不需要复制对象基础上允许Python代码访问。

【2】语法

memoryview(obj)
  • obj : 对象
  • 返回值 : 返回元组列表。

【3】示例

v = memoryview(bytearray("abcefg", 'utf-8'))
print(v[1])
# 98
print(v[-1])
# 103
print(v[1:4])
# <memory at 0x10f543a08>
print(v[1:4].tobytes())
# b'bce'

【二十二】object()函数(1)

【1】作用

  • Object类是Python中所有类的基类

    • 如果定义一个类时没有指定继承哪个类,则默认继承object类。
  • object没有定义__dict__

    • 所以不能对object类实例对象尝试设置属性。

【2】语法

object()
  • 返回值:
    • 返回一个新的无特征对象

【3】示例

class A:
    pass
print(issubclass(A,object)) #默认继承object类
 
print(dir(object)) #object类定义了所有类的一些公共方法

# True
# ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
  • object没有定义__dict__
    • 所以不能对object类实例对象尝试设置属性
# 定义一个类A
class A:
    pass
a = A()
a.name = 'li'  # 能设置属性
 
b = object()
b.name = 'wang' # 不能设置属性

# Traceback (most recent call last):
#  File "D:/Pythonproject/111/object.py", line 14, in <module>
#    b.name = 'wang' # 不能设置属性
#AttributeError: 'object' object has no attribute 'name'

【二十三】Python 中 property() 函数及 @property 装饰器的使用(1)

【1】property 应用场景

  • 在获取、设置和删除对象属性的时候,需要额外做一些工作。
    • 比如在游戏编程中,设置敌人死亡之后需要播放死亡动画。
  • 需要限制对象属性的设置和获取。
    • 比如用户年龄为只读,或者在设置用户年龄的时候有范围限制。
  • 这时就可以使用 property 工具,它把方法包装成属性,让方法可以以属性的形式被访问和调用

【2】property() 函数

  • 语法
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
  • fget获取属性值的方法
  • fset设置属性值的方法
  • fdel删除属性值的方法
  • doc属性描述信息。如果省略,会把 fget 方法的 docstring 拿来用(如果有的话)

【3】示例

class Student:
    def __init__(self):
        self._age = None

    def get_age(self):
        print('获取属性时执行的代码')
        return self._age

    def set_age(self, age):
        print('设置属性时执行的代码')
        self._age = age

    def del_age(self):
        print('删除属性时执行的代码')
        del self._age

    age = property(get_age, set_age, del_age, '学生年龄')


student = Student()
# 注意要用 类名.属性.__doc__ 的形式查看属性的文档字符串
print('查看属性的文档字符串:' + Student.age.__doc__)
"""
查看属性的文档字符串:学生年龄
"""

# 设置属性
student.age = 18
"""
设置属性时执行的代码
"""

# 获取属性
print('学生年龄为:' + str(student.age))
"""
获取属性时执行的代码
学生年龄为:18
"""

# 删除属性
del student.age
"""
删除属性时执行的代码
"""

【4】@property 装饰器

  • @property 语法糖提供了比 property() 函数更简洁直观的写法。

    • @property 装饰的方法是获取属性值的方法,被装饰方法的名字会被用做 属性名

    • @属性名.setter 装饰的方法是设置属性值的方法

    • @属性名.deleter 装饰的方法是删除属性值的方法

【5】示例(等价于 property()函数

class Student:
    def __init__(self):
        self._age = None

    @property
    def age(self):
        print('获取属性时执行的代码')
        return self._age

    @age.setter
    def age(self, age):
        print('设置属性时执行的代码')
        self._age = age

    @age.deleter
    def age(self):
        print('删除属性时执行的代码')
        del self._age


student = Student()

# 设置属性
student.age = 18
"""
设置属性时执行的代码
"""

# 获取属性
print('学生年龄为:' + str(student.age))
"""
获取属性时执行的代码
学生年龄为:18
"""

# 删除属性
del student.age
"""
删除属性时执行的代码
"""

【6】特别注意

  • 可以省略设置属性值的方法,此时该属性变成只读属性。如果此时仍然设置属性,会抛出异常 AttributeError: can't set attribute
  • 如果报错 RecursionError: maximum recursion depth exceeded while calling a Python object,很可能是对象属性名和 @property 装饰的方法名重名了,一般会在对象属性名前加一个下划线 _ 避免重名,并且表明这是一个受保护的属性。

【二十四】Python中super()详解及应用场景举例(1)

【1】作用

  • super也是一个类,是的。他不是一个方法也不是一个内置的关键字。
class A:
    pass

print(type(super(A)))

# <class 'super'>
  • 直接通过查看super的源码也可以看出它是一个类
class super(object):
    """
    super() -> same as super(__class__, <first argument>)
    super(type) -> unbound super object
    super(type, obj) -> bound super object; requires isinstance(obj, type)
    super(type, type2) -> bound super object; requires issubclass(type2, type)
    Typical use to call a cooperative superclass method:
    class C(B):
        def meth(self, arg):
            super().meth(arg)
    This works for class methods too:
    class C(B):
        @classmethod
        def cmeth(cls, arg):
            super().cmeth(arg)
    """
    def __getattribute__(self, *args, **kwargs): # real signature unknown
        """ Return getattr(self, name). """
        pass

    def __get__(self, *args, **kwargs): # real signature unknown
        """ Return an attribute of instance, which is of type owner. """
        pass

    def __init__(self, type1=None, type2=None): # known special case of super.__init__
        """
        super() -> same as super(__class__, <first argument>)
        super(type) -> unbound super object
        super(type, obj) -> bound super object; requires isinstance(obj, type)
        super(type, type2) -> bound super object; requires issubclass(type2, type)
        Typical use to call a cooperative superclass method:
        class C(B):
            def meth(self, arg):
                super().meth(arg)
        This works for class methods too:
        class C(B):
            @classmethod
            def cmeth(cls, arg):
                super().cmeth(arg)
        
        # (copied from class doc)
        """
        pass

    @staticmethod # known case of __new__
    def __new__(*args, **kwargs): # real signature unknown
        """ Create and return a new object.  See help(type) for accurate signature. """
        pass

    def __repr__(self, *args, **kwargs): # real signature unknown
        """ Return repr(self). """
        pass

    __self_class__ = property(lambda self: type(object))
    """the type of the instance invoking super(); may be None

    :type: type
    """

    __self__ = property(lambda self: type(object))
    """the instance invoking super(); may be None

    :type: type
    """

    __thisclass__ = property(lambda self: type(object))
    """the class invoking super()

    :type: type
    """

【2】纠正(super就是用来调用父类方法的,这是一个错误的观点!

class A:
    def __init__(self):
        print("A")


class B(A):
    def __init__(self):
        print("B")
        super().__init__()


class C(A):
    def __init__(self):
        print("C")
        super().__init__()


class D(B, C):
    def __init__(self):
        print("D")
        super().__init__()


D()

# D
# B
# C
# A
  • 如果按照“super就是用来调用父类的方法的”这样的理解来看,那上述代码的执行的过程应该为:

    • print("D")
    • 【调用super会先后执行B和C】
    • 先执行B:print("B")
    • 【调用super执行A】
    • print("A")
    • 【调用super会先后执行B和C】
    • 后执行C:print("C")
    • 【调用super执行A】
    • print("A")
  • 执行结果理论应该为:D B A C A

  • 但实际情况却是:D B C A

  • 所以说“super就是用来调用父类的方法的”这个说法是错误的!

  • 实际上super的调用是遵循Python的【MRO(方法解析顺序)】来执行的,在Python3中,MRO是基于C3算法来实现的。

【3】使用场景

  • 1.假如我们继承的多个父类有同名的方法
    • 可以使用super来指定使用哪个父类的方法
class A:
    def test(self):
        print('A')

class B:
    def test(self):
        print('B')

class C(A, B):
    def __init__(self):
        super().test()  # 调用A类中的test方法
        super(C, self).test()  # 调用A类中的test方法
        super(A, self).test()  # 调用B类中的test方法    
        
C()

# A
# A
# B
  • 2.当我们在子类中使用父类的一个方法并且想对其做一定扩展又不想完全重写,那么使用super()就可以实现方法的增量修改:
    • 举一个例子,如果我们想把list中的append的方法改为中文添加应该怎么做呢?
    • 并且python中list调用append方法是没有返回值的,我们想在添加元素操作成功后加一个返回值返回成功又该如何操作呢?
  • 首先看通过调用原来的list的执行结果
a=list()
res=a.append(1)
print(res)

# None
  • 可以看到调用append方法后返回的值为None
  • 现在我们通过super进行重写
    • 让其具有返回值并可以直接通过中文来调用append:
class 列表(list):
    def 添加(self, *args, **kwargs):
        super().append(*args, **kwargs)
        return "添加成功"

x = 列表()
res = x.添加(1)
print(res)
print(x)

# 添加成功
# [1]

【4】总结

  • super实际上还是很常用的
    • 比如在restfremework中
      • 需要重写其响应结果的Response信息的时候
      • 除了通过django的中间件实现
      • 也可以使用super重写其dispatch来实现。

【二十五】vars() 函数(1)

【1】作用

  • vars() 函数返回对象object的属性和属性值的字典对象。

【2】语法

vars([object])
  • object -- 对象

【3】返回值

  • 返回对象object的属性和属性值的字典对象
    • 如果没有参数,就打印当前调用位置的属性和属性值 类似 locals()。

【4】示例

print(vars())

# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000166DE910940>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:\\Old Boy\\day_projects\\day16\\text.py', '__cached__': None}
class Runoob:
    a = 1


print(vars(Runoob))
# {'__module__': '__main__', 'a': 1, '__dict__': <attribute '__dict__' of 'Runoob' objects>, '__weakref__': <attribute '__weakref__' of 'Runoob' objects>, '__doc__': None}
runoob = Runoob()
print(vars(runoob))
# {}
posted @ 2023-06-01 19:41  Chimengmeng  阅读(133)  评论(0编辑  收藏  举报