python内置函数2
python内置函数2
9. 对象操作
42. callable()
- 格式: callable(object)
- 返回值:如果参数 object 是可调用的就返回 True,否则返回 False。 如果返回 True,调用仍可能失败,但如果返回 False,则调用 object 将肯定不会成功。 请注意类是可调用的(调用类将返回一个新的实例);如果实例所属的类有 call() 则它就是可调用的。
3.2 新版功能: 这个函数一开始在 Python 3.0 被移除了,但在 Python 3.2 被重新加入。
# 如果参数 object 是可调用的就返回 True,否则返回 False。
print(f'{ callable(callable) = }')
def function():
pass
print(f'{ callable(function) = }')
print(f'{ callable(123) = }')
print(f'{ callable("test") = }')
'''
callable(callable) = True
callable(function) = True
callable(123) = False
callable("test") = False
'''
# 请注意类是可调用的(调用类将返回一个新的实例);
print('--------')
class C:
pass
print(f'{ callable(C) = }')
'''
callable(C) = True
callable(C()) = False
'''
# 如果实例所属的类有 __call__() 则它就是可调用的。
print(f'{ callable(C()) = }')
print('--------')
class C:
def __call__(self):
return "test"
print(f'{ callable(C()) = }')
print(f'{ C()() = }')
'''
callable(C()) = True
C()() = 'test'
'''
43. hash()
hash(object)
返回该对象的哈希值(如果它有的话)。哈希值是整数。它们在字典查找元素时用来快速比较字典的键。相同大小的数字变量有相同的哈希值(即使它们类型不同,如 1 和 1.0)。
注解 如果对象实现了自己的 hash() 方法,请注意,hash() 根据机器的字长来截断返回值。另请参阅 hash()
返回该对象的哈希值(如果它有的话)。哈希值是整数。
print(f'{ hash("test") = }')
print(f'{ hash("test") = }')
print(f'{ hash("test") = }')
print(f'{ hash((1, 2, 3)) = }')
print(f'{ hash(123456) = }')
相同大小的数字变量有相同的哈希值(即使它们类型不同,如 1 和 1.0)。
print(f'{ hash(1) = }')
print(f'{ hash(1.0) = }')
print(f'{ hash(1+0j) = }')
print(f'{ hash(True) = }')
45. id()
- 格式: id(object)
- 返回值: 返回对象的“标识值”。该值是一个整数,在此对象的生命周期中保证是唯一且恒定的。两个生命期不重叠的对象可能具有相同的 id() 值。
返回对象的“标识值”。该值是一个整数,在此对象的生命周期中保证是唯一且恒定的。
This is the address of the object in memory.
list_test = ["a", "b"]
print(f'{ id(list_test) = }')
print(f'{ hex(id(list_test)) = }')
str_test = "ab"
print(f'{ id(str_test) = }')
print(f'{ hex(id(str_test)) = }')
print('-------')
list_test.append("c")
print(f'{ id(list_test) = }')
str_test += "c"
print(f'{ id(str_test) = }')
引发一个 审计事件 builtins.id,附带参数 id。
import sys
def audit_hook(event, args):
if event in ['builtins.id']:
print(f'{ event = } { args = }')
sys.addaudithook(audit_hook)
print('------')
print(f'{ id("测试") = }')
46. len()
- 格式: len(s)
- 返回值: 返回对象的长度(元素个数)。实参可以是序列(如 string、bytes、tuple、list 或 range 等)或集合(如 dictionary、set 或 frozen set 等)。
返回对象的长度(元素个数)。实参可以是序列(如 string、bytes、tuple、list 或 range 等)或集合(如 dictionary、set 或 frozen set 等)。
print(f'{ len("abc") = }')
print(f'{ len(bytes("abc", "utf-8")) = }')
print(f'{ len(["a", "b", "c"]) = }')
print(f'{ len(("a", "b", "c")) = }')
print(f'{ len(range(3)) = }')
'''
len("abc") = 3
len(bytes("abc", "utf-8")) = 3
len(["a", "b", "c"]) = 3
len(("a", "b", "c")) = 3
len(range(3)) = 3
'''
print('------------')
print(f'{ len({"a":1, "b":2, "c":3}) = }')
print(f'{ len({"a", "b", "c"}) = }')
print(f'{ len(frozenset({"a", "b", "c"})) = }')
'''
len({"a":1, "b":2, "c":3}) = 3
len({"a", "b", "c"}) = 3
len(frozenset({"a", "b", "c"})) = 3
'''
47. object()
- 格式: class object
- 返回值: 返回一个没有特征的新对象。object 是所有类的基类。它具有所有 Python 类实例的通用方法。这个函数不接受任何实参。
由于 object 没有 dict,因此无法将任意属性赋给 object 的实例
#返回一个没有特征的新对象。
print(f'{ object() = }')
# object() = <object object at 0x000001587A5B0300>
#object 是所有类的基类。它具有所有 Python 类实例的通用方法。
print(f'{ object().__str__() = }')
print(f'{ object().__repr__() = }')
print(f'{ object().__hash__() = }')
print(f'{ object().__dir__() = }')
'''
object().__str__() = '<object object at 0x000001587A5B0300>'
object().__repr__() = '<object object at 0x000001587A5B0300>'
object().__hash__() = 92470095920
object().__dir__() = ['__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__', '__doc__']
'''
#由于 object 没有 __dict__,因此无法将任意属性赋给 object 的实例
print(f'{ hasattr(object, "__dict__") = }')
print(f'{ hasattr(object(), "__dict__") = }')
x = object()
x.test = 123
setattr(x, 'test', 123)
'''
hasattr(object, "__dict__") = True
hasattr(object(), "__dict__") = False
AttributeError: 'object' object has no attribute 'test'
'''
48. delattr(object, name)
实参是一个对象和一个字符串。该字符串必须是对象的某个属性。如果对象允许,该函数将删除指定的属性。
49. getattr(object, name[, default])
返回对象命名属性的值。name 必须是字符串。如果该字符串是对象的属性之一,则返回该属性的值。
50. hasattr(object, name)
该实参是一个对象和一个字符串。如果字符串是对象的属性之一的名称,则返回 True,否则返回 False。
51. setattr(object, name, value)
此函数与 getattr() 两相对应。 其参数为一个对象、一个字符串和一个任意值。 字符串指定一个现有属性或者新增属性。 函数会将值赋给该属性,只要对象允许这种操作。 例如,setattr(x, 'foobar', 123) 等价于 x.foobar = 123。
10. 类与实例
52. isinstance()
- 格式: isinstance(object, classinfo)
- 返回值: 如果参数 object 是参数 classinfo 的实例或者是其 (直接、间接或 虚拟) 子类则返回 True。 如果 object 不是给定类型的对象,函数将总是返回 False。
如果 classinfo 是类型对象元组(或由其他此类元组递归组成的元组),那么如果 object 是其中任何一个类型的实例就返回 True。 如果 classinfo 既不是类型,也不是类型元组或类型元组的元组,则将引发 TypeError 异常
# 如果参数 object 是参数 classinfo 的实例或者是其 (直接、间接或 虚拟) 子类则返回 True。
print(f'{ isinstance(True, bool) = }')
print(f'{ isinstance(123, int) = }')
print(f'{ isinstance("test", str) = }')
print('----')
class A:
pass
class B(A):
pass
class C(B):
pass
c = C()
print(f'{ isinstance(c, C) = }')
print(f'{ isinstance(c, B) = }')
print(f'{ isinstance(c, A) = }')
# 如果 object 不是给定类型的对象,函数将总是返回 False。
print('------')
print(f'{ isinstance(123, str) = }')
print(f'{ isinstance("test", bool) = }')
# 如果 classinfo 是类型对象元组(或由其他此类元组递归组成的元组),那么如果 object 是其中任何一个类型的实例就返回 True。
print('---------')
print(f'{ isinstance("test", (bool, int)) = }')
print(f'{ isinstance("test", (bool, int, str)) = }')
print(f'{ isinstance("test", (bool, (int, float, complex), (str, (bytes, bytearray)))) = }')
# 如果 classinfo 既不是类型,也不是类型元组或类型元组的元组,则将引发 TypeError 异常
print('---------')
# print(f'{ isinstance("test", "test") = }')
print(f'{ isinstance("test", [bool, int, str]) = }')
53. issubclass()
- 格式: issubclass(class, classinfo)
- 返回值: 如果 class 是 classinfo 的 (直接、间接或 虚拟) 子类则返回 True。 类会被视作其自身的子类。 classinfo 也以是类对象的元组,在此情况下 classinfo 中的每个条目都将被检查。 在任何其他情况下,都将引发 TypeError 异常。
# 如果 class 是 classinfo 的 (直接、间接或 虚拟) 子类则返回 True。
class A:
pass
class B(A):
pass
class C(B):
pass
print(f'{ issubclass(B, A) = }')
print(f'{ issubclass(C, B) = }')
print(f'{ issubclass(C, A) = }')
print(f'{ issubclass(C, int) = }')
# 类会被视作其自身的子类。
print('---')
print(f'{ issubclass(A, A) = }')
# classinfo 也以是类对象的元组,在此情况下 classinfo 中的每个条目都将被检查。
print('-----')
print(f'{ issubclass(B, (int, str)) = }')
print(f'{ issubclass(B, (int, str, A)) = }')
print(f'{ issubclass(B, (int, str, (float, A))) = }')
# 在任何其他情况下,都将引发 TypeError 异常。
print('-----------')
# print(f'{ issubclass(B, 123) = }')
# print(f'{ issubclass(B, [int, str, A]) = }')
54. type()
-
格式: class type(object)
class type(name, bases, dict) -
返回值: 传入一个参数时,返回 object 的类型。 返回值是一个 type 对象,通常与 object.class 所返回的对象相同。
# 传入一个参数时,返回 object 的类型。 返回值是一个 type 对象,通常与 object.__class__ 所返回的对象相同。
print(f'{ type("test") = }')
print(f'{ type(type("test")) = }')
print(f'{ "test".__class__ = }')
print(f'{ "test".__class__ == type("test") = }')
#
# 推荐使用 isinstance() 内置函数来检测对象的类型,因为它会考虑子类的情况。
#
# 传入三个参数时,返回一个新的 type 对象。 这在本质上是 class 语句的一种动态形式。 name 字符串即类名并且会成为 __name__ 属性;bases 元组列出基类并且会成为 __bases__ 属性;而 dict 字典为包含类主体定义的命名空间并且会被复制到一个标准字典成为 __dict__ 属性。
class Animal: pass
class Pet: pass
# class Cat(Animal, Pet):
# name = "小猫"
# age = 0
# def get_info(self):
# return f'小猫名字叫{self.name},今年{self.age}岁。'
def get_info(self):
info = f'小猫名字叫{self.name},今年{self.age}岁。'
return info
Cat = type('Cat',
(Animal, Pet),
# dict(name="小猫", age=0, get_info=lambda self: f'小猫名字叫{self.name},今年{self.age}岁。')
dict(name="小猫", age=0, get_info=get_info)
)
print('-----')
cat = Cat()
print(f'{ Cat.__name__ = }')
print(f'{ Cat.__bases__ = }')
print(f'{ Cat.__dict__ = }')
# print(f'{ cat.name = }')
# print(f'{ cat.age = }')
# print(f'{ cat.get_info() = }')
#
#
# 例如,下面两条语句会创建相同的 type 对象:
#
# >>>
# class X:
# a = 1
#
# X = type('X', (object,), dict(a=1))
# 另请参阅 类型对象。
#
# 在 3.6 版更改: type 的子类如果未重载 type.__new__,将不再能使用一个参数的形式来获取对象的类型。
11. 装饰器、描述器
55. classmethod()
- 格式: @classmethod
- 返回值: 把一个方法封装成类方法。
# 一个类方法把类自己作为第一个实参,就像一个实例方法把实例自己作为第一个实参。请用以下习惯来声明类方法:
# class C:
# @classmethod
# def f(cls, arg1, arg2, ...): ...
# @classmethod 这样的形式称为函数的 decorator -- 详情参阅 函数定义。
class C:
@classmethod
def f(*args):
print(f'{ args = }')
print(f'{ C.f = }')
C.f()
# 类方法的调用可以在类上进行 (例如 C.f()) 也可以在实例上进行 (例如 C().f())。 其所属类以外的类实例会被忽略。 如果类方法在其所属类的派生类上调用,则该派生类对象会被作为隐含的第一个参数被传入。
#
# 类方法的调用可以在类上进行 (例如 C.f()) 也可以在实例上进行 (例如 C().f())。 其所属类以外的类实例会被忽略。
class C:
@classmethod
def f(*args):
print(f'{ args = }')
print('-'*20)
C.f()
C().f()
# 如果类方法在其所属类的派生类上调用,则该派生类对象会被作为隐含的第一个参数被传入。
class D(C):
pass
print('-'*20)
D.f()
# 类方法与 C++ 或 Java 中的静态方法不同。 如果你需要后者,请参阅本节中的 staticmethod()。 有关类方法的更多信息,请参阅 标准类型层级结构。
#
# 注意点:@classmethod是一个装饰器,Python的装饰器可以像常规函数一样调用,所以classmethod可以像常规函数一样调用
class C:
# @classmethod
def f(*args):
print(f'{ args = }')
f = classmethod(f)
print('-'*20)
C.f()
# 在 3.9 版更改: 类方法现在可以包装其他 描述器 例如 property()。
# 在 3.9 版更改: 类方法现在可以包装其他 描述器 例如 property()。
# 这句话有个隐含的信息,classmethod()是一个描述器
# Python规定任何定义了__get__ __set__ __delete__特殊方法的类为描述器类,描述器类的实例是描述器
class C:
def f(*args):
print(f'{ args = }')
f = classmethod(f)
print('-'*20)
print(f'{ C.f = }')
print(f'{ C.__dict__["f"] = }')
print(f'{ C.__dict__["f"].__get__(None, C) = }')
print(f'{ C.__dict__["f"].__get__(None, C) == C.f = }')
56. property()
- 格式: class property(fget=None, fset=None, fdel=None, doc=None)
- 返回值: 返回 property 属性。
# fget 是获取属性值的函数。 fset 是用于设置属性值的函数。 fdel 是用于删除属性值的函数。并且 doc 为属性对象创建文档字符串。
# 一个典型的用法是定义一个托管属性 x:
# class C:
# def __init__(self):
# self._x = None
#
# def getx(self):
# return self._x
#
# def setx(self, value):
# self._x = value
#
# def delx(self):
# del self._x
# x = property(getx, setx, delx, "I'm the 'x' property.")
# 如果 c 是 C 的实例,c.x 将调用getter,c.x = value 将调用setter, del c.x 将调用deleter。
class C:
def __init__(self):
self._x = None
def setx(self, value):
print(f'调用了setx { value = }')
self._x = value
def delx(self):
print('调用了delx')
del self._x
def getx(self):
"""这是x属性的文档"""
print('调用了getx')
return self._x
# 如果 c 是 C 的实例,c.x 将调用getter,c.x = value 将调用setter, del c.x 将调用deleter。
# x = property(getx, setx, delx, "I'm the 'x' property.")
x = property(getx, setx, delx)
c = C()
# print(f'{ c.x = }')
# c.x = 123
# del c.x
# print(f'{ C.x.__doc__ = }')
#
# 如果给出,doc 将成为该 property 属性的文档字符串。 否则该 property 将拷贝 fget 的文档字符串(如果存在)。 这令使用 property() 作为 decorator 来创建只读的特征属性可以很容易地实现:
# class Parrot:
# def __init__(self):
# self._voltage = 100000
# @property
# def voltage(self):
# """Get the current voltage."""
# return self._voltage
# 以上 @property 装饰器会将 voltage() 方法转化为一个具有相同名称的只读属性的 "getter",并将 voltage 的文档字符串设置为 "Get the current voltage."
class Parrot:
def __init__(self):
self._voltage = 100000
@property
def voltage(self):
"""Get the current voltage."""
print('调用了voltage的getter')
return self._voltage
# voltage = property(voltage)
parrot = Parrot()
# print(f'{ parrot.voltage = }')
# print(f'{ Parrot.voltage.__doc__ = }')
# parrot.voltage = 200000
#
# 特征属性对象具有 getter, setter 以及 deleter 方法,它们可用作装饰器来创建该特征属性的副本,并将相应的访问函数设为所装饰的函数。 这最好是用一个例子来解释:
# class C:
# def __init__(self):
# self._x = None
# @property
# def x(self):
# """I'm the 'x' property."""
# return self._x
# @x.setter
# def x(self, value):
# self._x = value
# @x.deleter
# def x(self):
# del self._x
# 上述代码与第一个例子完全等价。 注意一定要给附加函数与原始的特征属性相同的名称 (在本例中为 x。)
# 返回的特征属性对象同样具有与构造器参数相对应的属性 fget, fset 和 fdel。
# 在 3.5 版更改: 特征属性对象的文档字符串现在是可写的。
# class C:
# def __init__(self):
# self._x = None
# def getx(self):
# return self._x
# def setx(self, value):
# self._x = value
# def delx(self):
# del self._x
# x = property(getx, setx, delx, "I'm the 'x' property.")
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
print('获取属性')
return self._x
# x = property(x)
@x.setter
def x(self, value):
print('设置属性')
self._x = value
# x = x.setter(x)
@x.deleter
def x(self):
print('删除属性')
del self._x
# x = x.deleter(x)
print('-'*20)
c = C()
# c.x
# c.x = 123
# del c.x
class C:
def __init__(self):
self._x = None
# @property
def x(self):
"""I'm the 'x' property."""
print('获取属性')
return self._x
x = property(x)
# @x.setter
def temp_x(self, value):
print('设置属性')
self._x = value
x = x.setter(temp_x)
# @x.deleter
def temp_x(self):
print('删除属性')
del self._x
x = x.deleter(temp_x)
print('-'*20)
c = C()
c.x
c.x = 123
del c.x
57. staticmethod()
- 格式: @staticmethod
- 返回值: 将方法转换为静态方法。
# 静态方法不会接收隐式的第一个参数。要声明一个静态方法,请使用此语法
#
# class C:
# @staticmethod
# def f(arg1, arg2, ...): ...
# @staticmethod 这样的形式称为函数的 decorator -- 详情参阅 函数定义。
class C:
@staticmethod
def f(*args):
print(f'{ args = }')
C.f()
C().f()
# 静态方法的调用可以在类上进行 (例如 C.f()) 也可以在实例上进行 (例如 C().f())。
#
# Python中的静态方法与Java或C ++中的静态方法类似。另请参阅 classmethod() ,用于创建备用类构造函数的变体。
#
# 像所有装饰器一样,也可以像常规函数一样调用 staticmethod ,并对其结果执行某些操作。比如某些情况下需要从类主体引用函数并且您希望避免自动转换为实例方法。对于这些情况,请使用此语法:
#
# class C:
# builtin_open = staticmethod(open)
# 想了解更多有关静态方法的信息,请参阅 标准类型层级结构 。
# 像所有装饰器一样,也可以像常规函数一样调用 staticmethod ,并对其结果执行某些操作。比如某些情况下需要从类主体引用函数并且您希望避免自动转换为实例方法。
class C:
# @staticmethod
def f(*args):
print(f'{ args = }')
f = staticmethod(f)
builtin_abs = staticmethod(abs)
print('-'*20)
C.f()
print(f'{ C.builtin_abs(-5) = }')
12. 代码编译与执行
58. eval()
- 格式: eval(expression[, globals[, locals]])
- 返回值: 返回对字符串的解析结果
实参是一个字符串,以及可选的 globals 和 locals。globals 实参必须是一个字典。locals 可以是任何映射对象。
a = 1
b = 2
print(f'{ eval("np.linspace(0,b,5)") = }')
print(f'{ eval("a+b") = }')
print(f'{ eval("a+b", dict(a=5, b=6)) = }')
c,d=eval(input())
'''
eval("np.linspace(0,b,5)") = array([0. , 0.5, 1. , 1.5, 2. ])
eval("a+b") = 3
eval("a+b", dict(a=5, b=6)) = 11
12,36
'''
59. complie()
- 格式:
compile(source, filename, mode, flags=0, dont_inherit=False, optimize=- 1)
将 source 编译成代码或 AST 对象。代码对象可以被 exec() 或 eval() 执行。source 可以是常规的字符串、字节字符串,或者 AST 对象。参见 ast 模块的文档了解如何使用 AST 对象。
filename 实参需要是代码读取的文件名;如果代码不需要从文件中读取,可以传入一些可辨识的值(经常会使用 '
mode 实参指定了编译代码必须用的模式。如果 source 是语句序列,可以是 'exec';如果是单一表达式,可以是 'eval';如果是单个交互式语句,可以是 'single'。(在最后一种情况下,如果表达式执行结果不是 None 将会被打印出来。)
# 将 source 编译成代码或 AST 对象。
# source 可以是常规的字符串
# filename 可以传入一些可辨识的值(经常会使用 '<string>')
# mode 实参指定了编译代码必须用的模式。如果 source 是语句序列,可以是 'exec';
# 代码对象可以被 exec() 或 eval() 执行。
src = """
for i in range(3):
print(i)
"""
print(f'{ compile(src, "<string>", "exec") = }')
exec(compile(src, "<string>", "exec"))
# mode 如果是单一表达式,可以是 'eval';
print(f'{ compile("1+2+3", "<string>", "eval") = }')
print(f'{ eval(compile("1+2+3", "<string>", "eval")) = }')
# mode 如果是单个交互式语句,可以是 'single'。
# src = "name=input('请输入你的名字:')"
# exec(compile(src, "<string>", "single"))
# print(f'{ name = }')
# source 可以是常规的字符串、字节字符串,或者 AST 对象。
print('---------')
src = bytes("print('test')", "utf-8")
print(f'{ compile(src, "<bytes>", "exec") = }')
exec(compile(src, "<bytes>", "exec"))
print('---------')
import ast
src = ast.parse("print('abc')")
print(f'{ compile(src, "<ast>", "exec") = }')
exec(compile(src, "<ast>", "exec"))
# 将 source 编译成代码或 AST 对象。
print('----------')
src = "print(123)"
print(f'{ compile(src, "<string>", "exec", flags=ast.PyCF_ONLY_AST) = }')
编译器选项和 future 语句是由比特位来指明的。 比特位可以通过一起按位 OR 来指明多个选项。 指明特定 future 特性所需的比特位可以在 future 模块的 Feature 实例的 compiler_flag 属性中找到。 编译器旗标 可以在 ast 模块中查找带有 PyCF 前缀的名称。
optimize 实参指定编译器的优化级别;默认值 -1 选择与解释器的 -O 选项相同的优化级别。显式级别为 0 (没有优化;debug 为真)、1 (断言被删除, debug 为假)或 2 (文档字符串也被删除)。
如果编译的源码不合法,此函数会触发 SyntaxError 异常;如果源码包含 null 字节,则会触发 ValueError 异常。
引发一个 审计事件 compile 附带参数 source, filename。
注解 在 'single' 或 'eval' 模式编译多行代码字符串时,输入必须以至少一个换行符结尾。 这使 code 模块更容易检测语句的完整性。
警告: 在将足够大或者足够复杂的字符串编译成 AST 对象时,Python 解释器有可能因为 Python AST 编译器的栈深度限制而崩溃。
60. exec()
- 格式: exec(object[, globals[, locals]])
- 返回值: None
这个函数支持动态执行 Python 代码。object 必须是字符串或者代码对象。如果是字符串,那么该字符串将被解析为一系列 Python 语句并执行(除非发生语法错误)。
exec("for i in range(3): print(i)")
# 如果是代码对象,它将被直接执行。
print('-----------')
print(f'{ compile("for i in range(3): print(i)", "<string>", "exec") = }')
print('-----------')
exec(compile("for i in range(3): print(i)", "<string>", "exec"))
# 这个函数支持动态执行 Python 代码。object 必须是字符串或者代码对象。如果是字符串,那么该字符串将被解析为一系列 Python 语句并执行(除非发生语法错误)。1 如果是代码对象,它将被直接执行。在任何情况下,被执行的代码都需要和文件输入一样是有效的(见参考手册中关于文件输入的章节)。请注意即使在传递给 exec() 函数的代码的上下文中,return 和 yield 语句也不能在函数定义之外使用。该函数返回值是 None 。
#
# 无论哪种情况,如果省略了可选项,代码将在当前作用域内执行。 如果只提供了 globals,则它必须是一个字典(不能是字典的子类),该字典将同时被用于全局和局部变量。 如果同时提供了 globals 和 locals,它们会分别被用于全局和局部变量。 如果提供了 locals,则它可以是任何映射对象。 请记住在模块层级上,globals 和 locals 是同一个字典。 如果 exec 得到两个单独对象作为 globals 和 locals,则代码将如同嵌入类定义的情况一样执行。
# # 无论哪种情况,如果省略了可选项,代码将在当前作用域内执行。 如果只提供了 globals,则它必须是一个字典(不能是字典的子类),该字典将同时被用于全局和局部变量。
a = 2
b = 3
print('---------')
exec("print(a*b)")
print('---------')
exec("print(a*b)", dict(a=5, b=6))
13. 可打印表示形式字符串
61. repr()
- 格式: repr(object)
- 返回值: printable
返回包含一个对象的可打印表示形式的字符串。
print(f'{ repr(123) = }')
print(f'{ str(123) = }')
print(f'{ repr(1.23) = }')
print(f'{ str(1.23) = }')
print(f'{ repr([1, 2, 3]) = }')
print(f'{ str([1, 2, 3]) = }')
print('------')
print(f'{ repr("abc") = }')
print(f'{ str("abc") = }')
print('------')
print(
len(repr("abc")),
len(str("abc")),
repr("abc")[0],
repr("a\"bc")[0],
repr("a'bc")[0],
repr("a'\"bc")[0],
)
print('------')
import datetime
date_test = datetime.date(year=1970, month=1, day=1)
print(f'{ repr(date_test) = }')
print(f'{ str(date_test) = }')
# repr(123) = '123'
# str(123) = '123'
# repr(1.23) = '1.23'
# str(1.23) = '1.23'
# repr([1, 2, 3]) = '[1, 2, 3]'
# str([1, 2, 3]) = '[1, 2, 3]'
# ------
# repr("abc") = "'abc'"
# str("abc") = 'abc'
# ------
# 5 3 ' ' " '
# ------
# repr(date_test) = 'datetime.date(1970, 1, 1)'
# str(date_test) = '1970-01-01'
对于许多类型来说,该函数会尝试返回的字符串将会与该对象被传递给 eval() 时所生成的对象具有相同的值,在其他情况下表示形式会是一个括在尖括号中的字符串,其中包含对象类型的名称与通常包括对象名称和地址的附加信息。 类可以通过定义 repr() 方法来控制此函数为它的实例所返回的内容。
print(f'{ eval(repr(123)) = }')
print(f'{ eval(repr(123)) == 123 = }')
print(f'{ eval(repr("test")) = }')
print(f'{ eval(repr("test")) == "test" = }')
print(f'{ eval(repr([1, 2, 3])) = }')
print(f'{ eval(repr([1, 2, 3])) == [1, 2, 3] = }')
# eval(repr(123)) = 123
# eval(repr(123)) == 123 = True
# eval(repr("test")) = 'test'
# eval(repr("test")) == "test" = True
# eval(repr([1, 2, 3])) = [1, 2, 3]
# eval(repr([1, 2, 3])) == [1, 2, 3] = True
62. ascii()
- 格式: ascii(object)
- 返回值: 返回一个对象可打印的字符串
repr() 返回的字符串中非 ASCII 编码的字符,会使用 \x、\u 和 \U 来转义。
print(f'{ ascii(123) = }')
print(f'{ repr(123) = }')
print(f'{ ascii(1.23) = }')
print(f'{ repr(1.23) = }')
print(f'{ ascii("test") = }')
print(f'{ repr("test") = }')
print(f'{ ascii([1, 2, 3]) = }')
print(f'{ repr([1, 2, 3]) = }')
# Unciode码点(码位、编号)
# 0~127 ASCII字符,不会使用\x \u \U转义字符
# 128~255 会使用\x转义字符
# 256~65535 会使用\u转义字符
# 65536~0x10ffff 会使用\U转义字符
print('---------')
print(f'{ ascii("test©汉😎") = }')
print(f'{ repr("test©汉😎") = }')
print(f'{ ascii(["test", "©", "汉", "😎"]) = }')
print(f'{ repr(["test", "©", "汉", "😎"]) = }')
# ascii(123) = '123'
# repr(123) = '123'
# ascii(1.23) = '1.23'
# repr(1.23) = '1.23'
# ascii("test") = "'test'"
# repr("test") = "'test'"
# ascii([1, 2, 3]) = '[1, 2, 3]'
# repr([1, 2, 3]) = '[1, 2, 3]'
# <class 'str'>
# ascii("test©汉😎") = "'test\\xa9\\u6c49\\U0001f60e'"
# repr("test©汉😎") = "'test©汉😎'"
# ascii(["test", "©", "汉", "😎"]) = "['test', '\\xa9', '\\u6c49', '\\U0001f60e']"
# repr(["test", "©", "汉", "😎"]) = "['test', '©', '汉', '😎']"
14. 其他
63. help()
启动内置的帮助系统(此函数主要在交互式中使用)。如果没有实参,解释器控制台里会启动交互式帮助系统。
如果实参是一个字符串,则在模块、函数、类、方法、关键字或文档主题中搜索该字符串,并在控制台上打印帮助信息。
如果实参是其他任意对象,则会生成该对象的帮助页。
64. super()
super() 函数是用于调用父类(超类)的一个方法。
65. locals()
更新并返回表示当前本地符号表的字典。 在函数代码块但不是类代码块中调用 locals() 时将返回自由变量。 请注意在模块层级上,locals() 和 globals() 是同一个字典。
注解 不要更改此字典的内容;更改不会影响解释器使用的局部变量或自由变量的值。
# 更新并返回表示当前本地符号表的字典。 在函数代码块但不是类代码块中调用 locals() 时将返回自由变量。
def f(arg):
v = 0
def f_test():
pass
class C():
pass
print(f'{ locals() = }')
f(1)
# 请注意在模块层级上,locals() 和 globals() 是同一个字典。
print('--------')
print(f'{ locals() == globals() = }')
# 注解 不要更改此字典的内容;更改不会影响解释器使用的局部变量或自由变量的值。
def f(arg):
v = 0
def f_test():
pass
class C():
pass
locals()['v'] = 3
print(f'{ v = }')
print(f'{ locals() = }')
print('------------')
f(1)
66. globals()
返回表示当前全局符号表的字典。这总是当前模块的字典(在函数或方法中,不是调用它的模块,而是定义它的模块)。
# 返回表示当前全局符号表的字典。
import sys
v = 0
def f(): pass
class C(): pass
print(f'{ globals() = }')
# 这总是当前模块的字典(在函数或方法中,不是调用它的模块,而是定义它的模块)。
import module_test
print('----------------------')
module_test.f1()
print('----------------------')
module_test.C1().m1()
# module test
# v1 = 0
# def f1():
# print(f'{ globals() = }')
# class C1():
# def m1(self):
# print(f'{ globals() = }')
67. vars()
vars() 函数返回对象object的属性和属性值的字典对象。
68. dir()
如果没有实参,则返回当前本地作用域中的名称列表。如果有实参,它会尝试返回该对象的有效属性列表。
dir函数可以列出对象的模块标识符,标识符有函数、类和变量。当你为dir函数提供一个模块名的时候,它返回模块定义的名称列表。如果不提供参数,它返回当前模块中定义的名称列表。
69. reload()
用于重新载入之前载入的模块。