设置类型、字典视图对象、上下文管理器、类与类实例(8)Python语言(必读进阶学习教程)(参考资料)
设置类型 – set
,frozenset
甲组对象是不同的无序集合可哈希对象。常见用途包括成员资格测试,从序列中删除重复项,以及计算数学运算,如交集,并集,差异和对称差异。(对于其它容器看到内置的dict
,list
和tuple
类和collections
模块)。
像其他收藏品,集支持,和。作为无序集合,集合不记录元素位置或插入顺序。因此,集合不支持索引,切片或其他类似序列的行为。x in set
len(set)
for x in set
目前有两种内置集类型,set
和frozenset
。的set
类型是可变的-内容可使用类似的方法来改变add()
和remove()
。由于它是可变的,因此它没有哈希值,不能用作字典键或另一组的元素。该frozenset
类型是不可变的和可散列的– 其内容在创建后不能更改; 因此,它可以用作字典键或另一组的元素。
非空集(不是frozensets)可以通过在大括号中放置以逗号分隔的元素列表来创建,例如:除了 构造函数之外。{'jack', 'sjoerd'}
set
两个类的构造函数的工作方式相同:
- class
set
([ iterable ] ) - class
frozenset
([ iterable ] ) - 返回一个新的set或frozenset对象,其元素取自 iterable。集合的元素必须是可以清除的。要表示集合集,内部集合必须是
frozenset
对象。如果未指定iterable,则返回新的空集。实例
set
并frozenset
提供以下操作:len(s)
- 返回集合的元素数小号(基数小号)。
x in s
- 测试x是否为s的成员资格。
x not in s
- 测试X在非会员小号。
isdisjoint
(其他)True
如果集合没有与其他元素共有的元素,则返回。当且仅当它们的交集是空集时,集是不相交的。
issubset
(其他)set <= other
- 测试集合中的每个元素是否在其他元素中。
set < other
- 测试集合是否是其他集合的适当子集,即 。
set <= other and set != other
issuperset
(其他)set >= other
- 测试其他元素是否在集合中。
set > other
- 测试集合是否是其他集合的正确超集,即。
set >= other and set != other
union
(*其他)set | other | ...
- 返回包含集合和所有其他元素的新集合。
intersection
(*其他)set & other & ...
- 返回一个新集合,其中包含集合和所有其他元素共有的元素。
difference
(*其他)set - other - ...
- 返回一个新集合,其中集合中的元素不在其他元素中。
symmetric_difference
(其他)set ^ other
- 返回一个新集合,其中包含集合中的元素或其他元素,但不是两者。
copy
()- 返回带有s的浅表副本的新集。
注意,对非运营商的版本
union()
,intersection()
,difference()
,和symmetric_difference()
,issubset()
和issuperset()
方法将接受任何可迭代作为参数。相比之下,他们基于运营商的同行要求他们的论点是集合。这排除了易于出错的结构,例如 更有可读性。set('abc') &'cbs'
set('abc').intersection('cbs')
两者
set
和frozenset
支持设置为设置比较。当且仅当每组中的每个元素都包含在另一组中时,两组相等(每组都是另一组的子集)。当且仅当第一组是第二组的适当子集(是子集,但不相等)时,集合小于另一个集合。当且仅当第一个集合是第二个集合的正确超集(是超集,但不相等)时,集合大于另一个集合。的实例
set
进行比较的情况下,frozenset
根据自己的成员。例如, 退货等等。set('abc') ==frozenset('abc')
True
set('abc') in set([frozenset('abc')])
子集和相等比较不推广到总排序函数。例如,任何两个非空不相交的集合不相等,并且不彼此的子集,所以所有的以下返回
False
:a<b
,a==b
,或a>b
。由于集合仅定义了部分排序(子集关系),因此
list.sort()
对于集合列表,方法的输出是未定义的。设置元素(如字典键)必须是可清除的。
混合
set
实例的二进制操作frozenset
返回第一个操作数的类型。例如:返回一个实例。frozenset('ab') |set('bc')
frozenset
下表列出了可用于的操作
set
,不适用于以下的不可变实例frozenset
:update
(*其他)set |= other | ...
- 更新集合,添加所有其他元素。
intersection_update
(*其他)set &= other & ...
- 更新集合,仅保留其中的元素和所有其他元素。
difference_update
(*其他)set -= other | ...
- 更新集合,删除其他人中找到的元素。
symmetric_difference_update
(其他)set ^= other
- 更新集合,仅保留在任一集中找到的元素,但不保留两者中的元素。
add
(elem )- 将元素elem添加到集合中。
remove
(elem )- 从集合中删除元素elem。
KeyError
如果elem未包含在集合中,则引发。
discard
(elem )- 如果存在,则从集合中删除元素elem。
pop
()- 从集合中删除并返回任意元素。
KeyError
如果集合为空则引发 。
clear
()- 从集合中删除所有元素。
需要注意的的非运营商的版本
update()
,intersection_update()
,difference_update()
,和symmetric_difference_update()
方法会接受任何迭代器作为参数。请注意,该ELEM参数的
__contains__()
,remove()
和discard()
方法可能是一组。为了支持搜索等效的冻结集,从elem创建临时冻结集。
映射类型 – dict
甲映射对象映射可哈希值到任意对象。映射是可变对象。目前只有一种标准的映射类型,即字典。(对于其它容器看到内置的 list
,set
和tuple
类和 collections
模块)。
字典的键几乎是任意值。不可 清除的值,即包含列表,字典或其他可变类型(通过值而不是按对象标识进行比较)的值不能用作键。用于键的数字类型遵循用于数字比较的常规规则:如果两个数字比较相等(例如1
和1.0
),则它们可以互换地用于索引相同的字典条目。(但请注意,由于计算机将浮点数存储为近似值,因此将它们用作字典键通常是不明智的。)
可以通过 在大括号中放置以逗号分隔的对列表来创建字典,例如:或,或由构造函数创建。key: value
{'jack':4098, 'sjoerd': 4127}
{4098: 'jack', 4127: 'sjoerd'}
dict
- class
dict
(** kwarg ) - class
dict
(mapping,** kwarg ) - class
dict
(iterable,** kwarg ) - 返回从可选位置参数和可能为空的关键字参数集初始化的新字典。
如果没有给出位置参数,则创建一个空字典。如果给出位置参数并且它是映射对象,则创建具有与映射对象相同的键 – 值对的字典。否则,位置参数必须是可迭代对象。iterable中的每个项目本身都必须是具有两个对象的可迭代项。每个项目的第一个对象成为新词典中的一个键,第二个对象成为相应的值。如果某个键出现多次,则该键的最后一个值将成为新字典中的相应值。
如果给出了关键字参数,则将关键字参数及其值添加到从位置参数创建的字典中。如果已添加的键已存在,则keyword参数中的值将替换位置参数中的值。
为了说明,以下示例都返回一个等于的字典 :
{"one": 1, "two": 2, "three": 3}
>>> >>> a = dict(one=1, two=2, three=3) >>> b = {'one': 1, 'two': 2, 'three': 3} >>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3])) >>> d = dict([('two', 2), ('one', 1), ('three', 3)]) >>> e = dict({'three': 3, 'one': 1, 'two': 2}) >>> a == b == c == d == e True
提供第一个示例中的关键字参数仅适用于有效Python标识符的键。否则,可以使用任何有效密钥。
这些是字典支持的操作(因此,自定义映射类型也应该支持):
len(d)
- 返回字典中的项目数d。
d[key]
- 用钥匙键返回d 项。引发
KeyError
if 键不在地图中。如果dict的子类定义了方法
__missing__()
并且键 不存在,则该d[key]
操作使用键键 作为参数调用该方法。然后d[key]
操作返回或引发__missing__(key)
调用返回或引发的任何内容。没有其他操作或方法调用__missing__()
。如果__missing__()
未定义,KeyError
则引发。__missing__()
必须是一种方法; 它不能是实例变量:>>> >>> class Counter(dict): ... def __missing__(self, key): ... return 0 >>> c = Counter() >>> c['red'] 0 >>> c['red'] += 1 >>> c['red'] 1
上面的例子显示了部分实现
collections.Counter
。使用不同的__missing__
方法collections.defaultdict
。
d[key] = value
- 设置
d[key]
为值。
del d[key]
d[key]
从d中删除。引发KeyError
if 键不在地图中。
key in d
True
如果d有钥匙钥匙,则返回False
。
key not in d
- 相当于。
not key in d
iter(d)
- 在字典的键上返回一个迭代器。这是一个捷径
iter(d.keys())
。
clear
()- 从字典中删除所有项目。
copy
()- 返回字典的浅表副本。
- classmethod
fromkeys
(iterable [,value ] ) - 使用来自iterable和值设置为value的键创建一个新字典。
fromkeys()
是一个返回新字典的类方法。值 默认为None
。
get
(键[,默认] )- 如果key在字典中,则返回key的值,否则返回default。如果未给出default,则默认为,因此此方法永远不会引发a 。
None
KeyError
items
()- 返回字典项目(对)的新视图。请参阅视图对象的文档。
(key, value)
keys
()- 返回字典键的新视图。请参阅视图对象的文档。
pop
(键[,默认] )- 如果key在字典中,则将其删除并返回其值,否则返回 default。如果未给出default并且key不在字典中,
KeyError
则引发a。
popitem
()- 从字典中删除并返回一对。对子以LIFO顺序退回。
(key, value)
popitem()
对于在字典中进行破坏性迭代很有用,就像在集合算法中经常使用的那样。如果字典为空,则调用popitem()
会引发aKeyError
。在版本3.7中更改:现在保证LIFO订单。在先前版本中,
popitem()
将返回任意键/值对。
setdefault
(键[,默认] )- 如果key在字典中,则返回其值。如果没有,插入钥匙 ,值为默认和返回默认值。 默认默认为
None
。
update
([ 其他] )- 更新与来自键/值对字典等,覆盖现有的密钥。返回
None
。update()
接受另一个字典对象或可重复的键/值对(作为元组或长度为2的其他迭代)。如果指定了关键字参数,则使用这些键/值对更新字典:。d.update(red=1, blue=2)
values
()- 返回字典值的新视图。请参阅视图对象的 文档。
当且仅当它们具有相同的对时,字典才会相等。订单比较('<‘,'<=’,’> =’,’>’)引发 。
(key,value)
TypeError
字典保留了插入顺序。请注意,更新密钥不会影响订单。删除后添加的键将在末尾插入。
>>> >>> d = {"one": 1, "two": 2, "three": 3, "four": 4} >>> d {'one': 1, 'two': 2, 'three': 3, 'four': 4} >>> list(d) ['one', 'two', 'three', 'four'] >>> list(d.values()) [1, 2, 3, 4] >>> d["one"] = 42 >>> d {'one': 42, 'two': 2, 'three': 3, 'four': 4} >>> del d["two"] >>> d["two"] = None >>> d {'one': 42, 'three': 3, 'four': 4, 'two': None}
在版本3.7中更改:字典顺序保证为插入顺序。此行为是来自3.6的CPython的实现细节。
也可以看看
types.MappingProxyType
可用于创建a的只读视图dict
。
字典视图对象
返回的对象的dict.keys()
,dict.values()
并且 dict.items()
是视图对象。它们提供字典条目的动态视图,这意味着当字典更改时,视图会反映这些更改。
可以迭代字典视图以生成各自的数据,并支持成员资格测试:
len(dictview)
- 返回字典中的条目数。
iter(dictview)
- 在字典中的键,值或项(表示为元组)上返回一个迭代器 。
(key, value)
键和值按插入顺序迭代。这允许使用以下方式创建对:。创建相同列表的另一种方法是。
(value,key)
zip()
pairs = zip(d.values(), d.keys())
pairs = [(v, k) for (k, v) in d.items()]
在字典中添加或删除条目时迭代视图可能会引发
RuntimeError
或不能遍历所有条目。在版本3.7中更改:字典顺序保证为插入顺序。
x in dictview
- 返回
True
如果X是在底层的字典的键,值或项(在后一种情况下,X应是一个元组)。(key, value)
键视图设置类似,因为它们的条目是唯一且可清除的。如果所有值都是可清除的,那么对是唯一且可清除的,那么items视图也是类似于set。(因为条目通常不是唯一值的观点不被视为设置状)。对于组样的观点,都为抽象基类中定义的操作的是可用的(例如,,,或)。(key, value)
collections.abc.Set
==
<
^
字典视图用法的示例:
>>> >>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500} >>> keys = dishes.keys() >>> values = dishes.values() >>> # iteration >>> n = 0 >>> for val in values: ... n += val >>> print(n) 504 >>> # keys and values are iterated over in the same order (insertion order) >>> list(keys) ['eggs', 'sausage', 'bacon', 'spam'] >>> list(values) [2, 1, 1, 500] >>> # view objects are dynamic and reflect dict changes >>> del dishes['eggs'] >>> del dishes['sausage'] >>> list(keys) ['bacon', 'spam'] >>> # set operations >>> keys & {'eggs', 'bacon', 'salad'} {'bacon'} >>> keys ^ {'sausage', 'juice'} {'juice', 'sausage', 'bacon', 'spam'}
上下文管理器类型
Python的with
语句支持由上下文管理器定义的运行时上下文的概念。这是使用一对方法实现的,这些方法允许用户定义的类定义在语句体执行之前输入的运行时上下文,并在语句结束时退出:
contextmanager.
__enter__
()- 输入运行时上下文并返回此对象或与运行时上下文相关的其他对象。此方法返回的值绑定到使用此上下文管理器
as
的with
语句子句中的标识符。返回自身的上下文管理器的示例是文件对象。文件对象从__enter __()返回,以允许
open()
在with
语句中用作上下文表达式。返回相关对象的上下文管理器的示例是返回的对象
decimal.localcontext()
。这些管理器将活动的十进制上下文设置为原始十进制上下文的副本,然后返回该副本。这允许对with
语句正文中的当前十进制上下文进行更改,而不会影响with
语句外的代码 。
contextmanager.
__exit__
(exc_type,exc_val,exc_tb )- 退出运行时上下文并返回一个布尔标志,指示是否应该抑制发生的任何异常。如果在执行
with
语句主体时发生异常,则参数包含异常类型,值和回溯信息。否则,所有三个参数都是None
。从此方法返回true值将导致
with
语句禁止异常并继续执行紧跟语句后面的with
语句。否则,在此方法执行完毕后,异常将继续传播。执行此方法期间发生的异常将替换with
语句正文中发生的任何异常。传入的异常永远不应该显式重新标记 – 相反,此方法应返回false值以指示方法已成功完成且不希望抑制引发的异常。这允许上下文管理代码轻松检测
__exit__()
方法是否实际失败。
Python定义了几个上下文管理器,以支持简单的线程同步,文件或其他对象的快速关闭,以及对活动十进制算术上下文的简单操作。除了实现上下文管理协议之外,特定类型不会被特别处理。有关contextlib
示例,请参阅 模块。
Python的生成器和contextlib.contextmanager
装饰器提供了一种实现这些协议的便捷方式。如果使用contextlib.contextmanager
装饰器修饰生成器函数,它将返回实现必要__enter__()
和 __exit__()
方法的上下文管理器,而不是由未修饰的生成器函数生成的迭代器。
请注意,Python / C API中Python对象的类型结构中没有针对这些方法的特定插槽。想要定义这些方法的扩展类型必须将它们作为普通的Python可访问方法提供。与设置运行时上下文的开销相比,单个类字典查找的开销可以忽略不计。
其他内置类型
解释器支持其他几种对象。其中大多数只支持一两个操作。
模块
模块上唯一的特殊操作是属性访问:m.name
其中 m是模块,名称访问m的符号表中定义的名称。可以将模块属性分配给。(请注意import
,严格来说,该语句不是对模块对象的操作; 不需要存在名为foo的模块对象,而是需要某个名为foo的模块的(外部)定义。)import foo
每个模块的特殊属性是__dict__
。这是包含模块符号表的字典。修改这个字典实际上会改变模块的符号表,但不能直接赋值给 __dict__
属性(你可以编写 ,定义为,但你不能写 )。不建议直接修改。m.__dict__['a'] =1
m.a
1
m.__dict__ = {}
__dict__
内置于解释器中的模块如下所示:。如果从文件加载,则将其写为。<module 'sys' (built-in)>
<module 'os'from '/usr/local/lib/pythonX.Y/os.pyc'>
类和类实例
请参阅对象,值和类型以及这些的类定义。
功能
函数对象由函数定义创建。函数对象的唯一操作是调用它:func(argument-list)
。
实际上有两种函数对象:内置函数和用户定义函数。两者都支持相同的操作(调用函数),但实现方式不同,因此不同的对象类型。
有关更多信息,请参阅函数定义
方法
方法是使用属性表示法调用的函数。有两种风格:内置方法(如append()
列表)和类实例方法。内置方法用支持它们的类型描述。
如果通过实例访问方法(类名称空间中定义的函数),则会得到一个特殊对象:绑定方法(也称为 实例方法)对象。调用时,它会将self
参数添加到参数列表中。绑定方法有两个特殊的只读属性: m.__self__
是方法操作的对象,m.__func__
是实现该方法的函数。通话 完全等同于通话。m(arg-1, arg-2, ..., arg-n)
m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)
与函数对象一样,绑定的方法对象支持获取任意属性。但是,由于方法属性实际存储在底层函数对象(meth.__func__
)中,因此不允许在绑定方法上设置方法属性。尝试在方法上设置属性会导致AttributeError
被引发。要设置方法属性,需要在底层函数对象上显式设置它:
>>> >>> class C: ... def method(self): ... pass ... >>> c = C() >>> c.method.whoami = 'my name is method' # can't set on the method Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'method' object has no attribute 'whoami' >>> c.method.__func__.whoami = 'my name is method' >>> c.method.whoami 'my name is method'
有关更多信息,请参阅标准类型层次结构
代码对象
实现使用代码对象来表示“伪编译”的可执行Python代码,例如函数体。它们与函数对象不同,因为它们不包含对其全局执行环境的引用。代码对象由内置compile()
函数返回,可以通过其__code__
属性从函数对象中提取。另见code
模块。
A码对象可以被执行或通过将其(而不是源字符串)所评估的exec()
或eval()
内置函数。
有关更多信息,请参阅标准类型层次结构
空对象
此函数由未显式返回值的函数返回。它不支持任何特殊操作。只有一个名为None
(内置名称)的空对象 。type(None)()
产生相同的单身人士。
它写成None
。
省略号对象
切片通常使用此对象(请参阅切片)。它不支持任何特殊操作。只有一个省略号对象,名为 Ellipsis
(内置名称)。 type(Ellipsis)()
产生 Ellipsis
单身人士。
它写成Ellipsis
或...
。
NotImplemented对象
当要求对它们不支持的类型进行操作时,将从比较和二进制操作返回此对象。有关详细信息,请参阅比较。只有一个NotImplemented
对象。 type(NotImplemented)()
生成单例实例。
它写成NotImplemented
。
布尔值
布尔值是两个常量对象False
和True
。它们用于表示真值(尽管其他值也可以被认为是假或真)。在数字上下文中(例如,当用作算术运算符的参数时),它们的行为分别与整数0和1相似。bool()
如果值可以被解释为真值,则内置函数可用于将任何值转换为布尔值(请参阅上面的真值测试部分 )。
它们分别写成False
和True
。
内部对象
请参阅此信息的标准类型层次结构。它描述了堆栈帧对象,回溯对象和切片对象。
特殊属性
该实现为几个对象类型添加了一些特殊的只读属性,它们是相关的。其中一些内容功能未报告 dir()
。
object.
__dict__
- 用于存储对象(可写)属性的字典或其他映射对象。
instance.
__class__
- 类实例所属的类。
class.
__bases__
- 类对象的基类的元组。
definition.
__name__
- 类,函数,方法,描述符或生成器实例的名称。
definition.
__qualname__
- 类,函数,方法,描述符或生成器实例的限定名称。
版本3.3中的新功能。
class.
__mro__
- 此属性是在方法解析期间查找基类时考虑的类的元组。
class.
mro
()- 元类可以重写此方法,以自定义其实例的方法解析顺序。它在类实例化时调用,其结果存储在
__mro__
。
class.
__subclasses__
()- 每个类都保留一个对其直接子类的弱引用列表。此方法返回所有仍然存活的引用的列表。例:
>>> int.__subclasses__() [<class 'bool'>]
脚注
[1] | 有关这些特殊方法的更多信息,请参阅Python参考手册(基本自定义)。 |
[2] | 因此,列表被认为是等同的,并且类似于元组。[1, 2] [1.0, 2.0] |
[3] | 它们必须具有,因为解析器无法分辨操作数的类型。 |
[4] | (1,2,3,4)下套管字符是那些具有一般类别属性是“路”(字母,大写),“LL”(字母,小写),或“LT”(字母,首字母大写)中的一个。 |
[5] | (1,2)要格式化只有一个元组因此,你应该提供一个单元组的唯一元件是要格式化的元组。 |