python内置函数 I
Python 解释器内置了很多函数和类型,任何时候都能使用。
I
名称 | 描述 |
---|---|
id | 返回对象的“标识符”。 |
input | 返回一个字符串类型的值,即用户输入的文本。 |
int | 将一个数或字符串转换成整数。 |
isinstance | 检查一个对象是否是一个已知的类型(类)的实例,或者是否属于一个指定的类型元组中的任意类型。 |
issubclass | 检查一个类是否是另一个类的子类。 |
iter | 获取一个对象的迭代器。 |
id(object)
返回对象的“标识值”。该值是一个整数,在此对象的生命周期中保证是唯一且恒定的。两个生命期不重叠的对象可能具有相同的 id()
值。
CPython 实现细节: 这是对象在内在中的地址。
引发一个 审计事件 builtins.id
,附带参数 id
。
x = 10
print(id(x)) # 输出x对象的内存地址
y = [1, 2, 3]
print(id(y)) # 输出y对象的内存地址
z = id(y)
print(z) # 输出与上面相同的内存地址,因为z是y的内存地址的引用
# 不可变对象
a = 123
b = 123
print(a is b) # 输出True,因为a和b指向相同的内存地址(对于小的整数,Python会缓存它们)
print(id(a) == id(b)) # 输出True,因为它们的id相同
s1 = "hello"
s2 = "hello"
print(s1 is s2) # 输出True,因为字符串在Python中也是不可变的,并且短字符串会被缓存
print(id(s1) == id(s2)) # 输出True,它们的id相同
# 可变对象
l1 = [1, 2, 3]
l2 = [1, 2, 3]
print(l1 is l2) # 输出False,因为l1和l2是两个不同的对象,即使它们的内容相同
print(id(l1) == id(l2)) # 输出False,它们的id不同
id()
函数返回的标识符是唯一的,并且在对象的生命周期内保持不变。- 对于不可变对象(如整数、字符串、元组),具有相同值的对象可能具有不同的身份(即不同的内存地址)。
- 对于可变对象(如列表、字典、集合),即使两个对象具有相同的内容,它们的身份也可能不同。
id()
函数主要用于调试和某些低级编程任务,通常不用于日常编程。
input()
input()
input(prompt)
如果存在 prompt 实参,则将其写入标准输出,末尾不带换行符。接下来,该函数从输入中读取一行,将其转换为字符串(除了末尾的换行符)并返回。当读取到 EOF 时,则触发 EOFError
。例如:
>>> s = input('--> ')
--> Monty Python's Flying Circus
>>> s
"Monty Python's Flying Circus"
如果加载了 readline
模块,input()
将使用它来提供复杂的行编辑和历史记录功能。
# readline模块在Windows上可能不可用,因为它依赖于UNIX风格的行编辑功能。在Windows上,可以使用pyreadline模块作为readline的替代品。
# pip install pyreadline
# 在交互式Python shell中运行它,就可以实现历史记录的保存和加载。
import readline
import os
# 获取用户的家目录
histfile = os.path.join(os.path.expanduser('~'), '.python_history')
try:
# 尝试读取历史记录
readline.read_history_file(histfile)
readline.set_history_length(1000) # 设置历史记录长度
except FileNotFoundError:
pass
def save_history(histfile=histfile):
readline.write_history_file(histfile)
# 注册atexit处理函数,在退出时保存历史记录
import atexit
atexit.register(save_history)
del os, histfile, readline, save_history
# readline模块和pyreadline模块主要关注于交互式命令行环境的编辑和补全功能,对于一般的文件读取操作,使用文件对象的readline()方法就足够了。
'''
readline.read_history_file(filename): 从文件中读取命令行历史。
readline.write_history_file(filename): 将命令行历史写入文件。
readline.parse_and_bind(string): 将readline命令绑定到键序列。
readline.get_history_item(index): 获取历史记录中的特定项。
readline.get_history_length(): 获取历史记录的长度。
readline.set_history_length(length): 设置历史记录的长度。
'''
引发一个 审计事件 builtins.input
附带参数 prompt
。
在成功读取输入之后引发一个 审计事件 builtins.input/result
附带结果。
# 获取用户姓名
name = input("请输入你的名字: ")
print("你好, " + name + "!")
# 获取用户年龄并尝试转换为整数
age_str = input("请输入你的年龄: ")
age = int(age_str) # 这里假设用户会输入一个有效的整数
print("你的年龄是: ", age)
# 获取用户选择并比较
choice = input("请选择A或B: ")
if choice == "A":
print("你选择了A")
elif choice == "B":
print("你选择了B")
else:
print("无效的选择")
input()
函数总是返回一个字符串,即使输入的是数字。如果你需要数字或其他类型的数据,你需要使用相应的类型转换函数(如int()
,float()
,bool()
等)来转换输入。- 在处理用户输入时,应该总是考虑到错误处理和异常处理,因为用户可能会输入无效的数据。
input()
函数在等待用户输入时会阻塞程序的执行,直到用户输入了内容并按下回车键。
try:
age_str = input("请输入你的年龄: ")
age = int(age_str) # 尝试将输入转换为整数
print("你的年龄是: ", age)
except ValueError:
print("无效的年龄输入,请输入一个整数。")
int(x=0)
class int(x=0)
class int(x, base=10)
返回一个基于数字或字符串 x 构造的整数对象,或者在未给出参数时返回 0
。 如果 x 定义了 __int__()
,则 int(x)
将返回 x.__int__()
。 如果 x 定义了 __index__()
,则将返回 x.__index__()
。 如果 x 定义了 __trunc__()
,则将返回 x.__trunc__()
。 对于浮点数,这将向零方向截断。
如果 x 不是一个数字或者如果给定了 base,则 x 必须是一个表示以 base 为基数的整数的字符串、bytes
或 bytearray
实例。 字符串前面还能加上可选的 +
或 -
(中间没有空格),带有前导的零,带有两侧的空格,并可带有数位之间的单个下划线。
一个以 n 为基数的整数字符串包含多个数位,每个数位代表从 0 到 n-1 范围内的值。 0–9 的值可以用任何 Unicode 十进制数码来表示。 10–35 的值可以用 a
到 z
(或 A
到 Z
) 来表示。 默认的 base 为 10。 允许的基数为 0 和 2–36。 对于基数 2, 8 和 16 来说字符串前面还能加上可选的 0b
/0B
, 0o
/0O
或 0x
/0X
前缀,就像代码中的整数字面值那样。 对于基数 0 来说,字符串会以与 代码中的整数字面值 类似的方式来解读,即实际的基数将由前缀确定为 2, 8, 10 或 16。 基数为 0 还会禁用前导的零: int('010', 0)
将是无效的,而 int('010')
和 int('010', 8)
则是有效的。
整数类型定义请参阅 数字类型 — int, float, complex 。
在 3.4 版本发生变更: 如果 base 不是 int
的实例,但 base 对象有 base.__index__
方法,则会调用该方法来获取进制数。以前的版本使用 base.__int__
而不是 base.__index__
。
在 3.6 版本发生变更: 您可以使用下划线将代码文字中的数字进行分组。
在 3.7 版本发生变更: x 现在只能作为位置参数。
在 3.8 版本发生变更: 如果 __int__()
未定义则回退至 __index__()
。
在 3.11 版本发生变更: 委托给 __trunc__()
的做法已被弃用。
在 3.11 版本发生变更: int
字符串输入和字符串表示形式可受到限制以帮助避免拒绝服务攻击。 当将一个字符串 x 转换为 int
或者当将一个 int
转换为字符串的操作超出限制则会引发 ValueError
。 请参阅 整数字符串转换长度限制 文档。
# 将浮点数转换为整数:int() 函数会向下取整,即丢弃小数部分。
num = 3.9
integer_num = int(num)
print(integer_num) # 输出: 3
# 将字符串转换为整数:如果字符串表示一个有效的整数,int() 函数可以将其转换成一个整数。
str_num = "123"
int_num = int(str_num)
print(int_num) # 输出: 123
str_num = "123abc"
# int_num = int(str_num) # 这会引发 ValueError: invalid literal for int() with base 10: '123abc'
hex_num = "1A"
int_num = int(hex_num, 16) # 将十六进制数 "1A" 转换为十进制数
print(int_num) # 输出: 26
int()
函数仅用于将数值或表示数值的字符串转换为整数。如果你尝试将一个非数值或非数值表示的字符串传递给 int()
,你会得到一个 ValueError
。
isinstance(object, classinfo)
isinstance()
是一个内置函数,用于检查一个对象是否是一个已知的类型(类)的实例,或者是否属于一个指定的类型元组中的任意类型。
object
:要检查的对象。classinfo
:可以是直接或间接类名、基本类型或者由它们组成的元组。
如果 object 参数是 classinfo 参数的实例,或者是其 (直接、间接或 虚拟) 子类的实例则返回 True
。 如果 object 不是给定类型的对象,则该函数总是返回 False
。 如果 classinfo 是由类型对象结成的元组 (或是由其他此类元组递归生成) 或者是多个类型的 union 类型,则如果 object 是其中任一类型的实例时将会返回 True
。 如果 classinfo 不是一个类型或类型元组及此类元组,则会引发 TypeError
异常。 如果之前的检查成功执行则可以不会为无效的类型引发 TypeError
。
在 3.10 版本发生变更: classinfo 可以是一个 union 类型。
# 检查一个对象是否是整数类型
x = 10
print(isinstance(x, int)) # 输出: True
# 检查一个对象是否是字符串类型
y = "hello"
print(isinstance(y, str)) # 输出: True
# 检查一个对象是否是元组中的任一类型
z = 3.14
print(isinstance(z, (int, float))) # 输出: True
# 检查一个对象是否不是指定的类型
print(isinstance(z, str)) # 输出: False
# 多态性
def process_input(input_value):
if isinstance(input_value, (int, float)):
print(f"Processing a number: {input_value}")
elif isinstance(input_value, str):
print(f"Processing a string: {input_value}")
else:
print("Unsupported type")
process_input(10) # 输出: Processing a number: 10
process_input("hello") # 输出: Processing a string: hello
process_input([1, 2, 3]) # 输出: Unsupported type
isinstance()
总是考虑继承关系。如果一个类继承自另一个类,那么isinstance()
会认为该类的实例也是父类的实例。- 与
type()
函数不同,isinstance()
允许你检查一个对象是否是多个类型中的一个,这是通过将类型作为元组传递给isinstance()
来实现的。 isinstance()
在处理多态性时非常有用,它允许你编写能够处理多种类型输入的函数和方法。
issubclass(class, classinfo)
issubclass()
是一个内置函数,用于检查一个类是否是另一个类的子类。
class
:要检查的类。classinfo
:可以是类对象,也可以是类对象的元组,用于检查class
是否是classinfo
的子类。
如果 class 是 classinfo 的子类(直接、间接或 虚的 ),则返回 True
。类将视为自己的子类。classinfo 可为类对象的元组(或递归地,其他这样的元组)或 union 类型,这时如果 class 是 classinfo 中任何条目的子类,则返回 True
。任何其他情况都会触发 TypeError
异常。
在 3.10 版本发生变更: classinfo 可以是一个 union 类型。
class A:
pass
class B(A):
pass
class C:
pass
# 检查B是否是A的子类
print(issubclass(B, A)) # 输出: True
# 检查A是否是B的子类(实际上不是)
print(issubclass(A, B)) # 输出: False
# 检查C是否是A的子类(实际上不是)
print(issubclass(C, A)) # 输出: False
# 检查B是否是A或C的子类
print(issubclass(B, (A, C))) # 输出: True
# 检查A是否是B或C的子类(实际上不是)
print(issubclass(A, (B, C))) # 输出: False
# 处理类层次结构
def process_class(cls):
if issubclass(cls, A):
print(f"Processing a subclass of A: {cls.__name__}")
else:
print(f"Processing a non-subclass of A: {cls.__name__}")
process_class(B) # 输出: Processing a subclass of A: B
process_class(C) # 输出: Processing a non-subclass of A: C
issubclass()
函数总是考虑继承关系。如果一个类继承自另一个类,那么issubclass()
会认为该类是父类的子类。- 与
isinstance()
函数不同,issubclass()
用于比较类与类之间的关系,而不是对象与类型之间的关系。 issubclass()
在处理类层次结构时非常有用,特别是在需要编写通用代码时,能够处理不同类型的子类。
iter(object)
iter(object)
iter(object, sentinel)
iter()
是一个内置函数,用于获取一个对象的迭代器。迭代器是一个可以记住遍历的位置的对象,它允许你遍历容器(如列表、元组或字典)中的元素。
- 当只有一个参数时,
iter(iterable)
返回一个迭代器对象,该对象在遍历时会生成iterable
中的元素。 - 当有两个参数时,
iter(callable, sentinel)
创建一个迭代器,每次调用callable
时都会生成一个新的值,直到这个值等于sentinel
时停止。
返回一个 iterator 对象。 根据是否存在第二个参数,对第一个参数的解读会有很大的不同。 如果没有第二个参数,object 必须是一个支持 iterable 协议 (有 __iter__()
方法) 的多项集对象,或者必须支持序列协议 (有 __getitem__()
方法并使用从 0
开始的整数参数)。 如果它不支持这些协议,则会引发 TypeError
。 如果给出了第二个参数 sentinel,则 object 必须是一个可调用对象。 在这种情况下创建的迭代器将针对每次调用其 __next__()
方法不带参数地调用 object;如果返回的值等于 sentinel,则会引发 StopIteration
,否则将返回该值。
另请参阅 迭代器类型。
适合 iter()
的第二种形式的应用之一是构建块读取器。 例如,从二进制数据库文件中读取固定宽度的块,直至到达文件的末尾:
from functools import partial
with open('mydata.db', 'rb') as f:
for block in iter(partial(f.read, 64), b''):
process_block(block)
# 单一参数
my_list = [1, 2, 3, 4]
it = iter(my_list)
# 使用 next() 函数获取下一个元素
print(next(it)) # 输出: 1
print(next(it)) # 输出: 2
print(list(it)) # 输出: [3, 4]
# 当所有元素都被获取后,next() 会引发 StopIteration 异常。
# 两个参数
import random
values = [i for i in range(1, 7)]
def number_chocie():
return random.choice(values)
# 创建一个迭代器,当生成的值等于 5 时停止
it = iter(number_chocie, 5)
# 使用 next() 函数从迭代器中获取值
try:
while True:
print(next(it))
except StopIteration:
pass
- 当你尝试从迭代器中获取更多的元素,而迭代器中没有更多的元素时,
next()
函数会引发StopIteration
异常。这通常用于表示迭代的结束。 - 并非所有对象都是可迭代的。一个对象必须是实现了
__iter__()
或__getitem__()
方法的实例,才能通过iter()
函数转换为迭代器。
for
循环在Python中实际上是通过迭代器工作的。当你对一个可迭代对象(如列表、元组、字典或集合)使用 for
循环时,Python 会自动调用该对象的 __iter__()
方法来获取一个迭代器,并使用 next()
函数来遍历所有元素,直到引发 StopIteration
异常为止。