常见的内置函数和关键字之python篇
1 input 和 print
完整的print
print(*values, sep=' ', end='\n',file=sys.stdout, flush=False)
简单的value表示可用提供任意数量的位置参数给 print,它将正确打印。 默认使用空格分隔
使用print将输出打印到文件
with open('test.txt', 'w') as f:
print("hello!", file=f)
有些语言有特殊对象,可用让你调用print方法,通过使用熟悉的print接口写入文件。
在python,您可更进一步,临时配置print函数默认写入文件
sys.stdout = open('mytext.txt', 'w')
flush是print函数的布尔标志。它所做的只是告诉print将文本立即写入控制台/文件,而不是将其放入缓冲区中。
这通常没有太大的区别,但是如果您将一个非常大的字符串打印到控制台,您可能希望将其设置True 为避免向用户显示输出时出现滞后
2 五个基本数据类型关键字 str, bytes, int, bool, float, complex
基于文本的数据类型
-
字符串类型 str
-
字节码 bytes
实际上是计算中所有I/O的基础,如果您了解计算机,所有数据其实
都以位和字节存储和处理,这是终端的真正工作方式
sys模块的I/O缓冲区sys.stdout.buffer sys.stdin.buffer
缓冲区对象接收butes,将它们直接写入输出缓冲区,并返回字节数
>>> char_count = sys.stdout.buffer.write("hello!\n".encode()) hello! >>> char_count 7
为了证明都是字节,另一个字节打印表情符号的示例
b'\xf0\x9f\x90\x8d' # 🐍的utf-8编码 encoded string of the snake emoji _ = sys.stdout.buffer.write(b'\xf0\x9f\x90\x8d') 🐍
int是另一种广泛使用的基本原始数据类型。
它也是 2 种其他数据类型的最小公分母:float和complex. complex是 的超类型float,而后者又是 的超类型int。
3 mro对这些类的属性来自行检查
mro 代表 方法解析顺序,它定义了查找类调用方法的顺序。
本质上,方法调用首先在类本身调用如果它不存在,则在父类搜索,然后在其父类的父类搜索一直到顶部。
object.python的所有内容都继承自object,是的,python的几乎所有东西都是对象
>>> int.mro()
[<class 'int'>, <class 'object'>]
>>> float.mro()
[<class 'float'>, <class 'object'>]
>>> complex.mro()
[<class 'complex'>, <class 'object'>]
>>> str.mro()
[<class 'str'>, <class 'object'>]
>>> bool.mro()
[<class 'bool'>, <class 'int'>, <class 'object'>]
您可从它们 “根”类型 看出,所有其他数据类型都不是任何东西的 子类 除了 object 它将永远存在,除了bool 它继承自int。
现在 您可能希望知道 为什么要bool subclass int,这主要是因为兼容性原因。
所以您都可用在预期bool 的任何地方传递 一个 int。
4 对象 object
obj.x通过调用__getattr__的方法访问属性。
类似地 setattr 设置一个新属性和 __delattr__删除一个属性分别调用和。
对象的哈希是通过预定义的__hash__方法生成的,对象的字符串表示来自__repr__。
而python的所有对象都是object.
5 hash和id 相等
内置函数 hash 和 id 构成了python对象是否相等的支持默认情况下,python对象是不可比较的,除非它们相同。
A = object()
B = object()
A == B
False
object也被称为哨兵,因为它们可用于准确检查无法复制的值
__my_sentinel = object()
def what_was_passed(value=__my_sentinel):
if value is __my_sentinel:
print('Nothing was passed.')
else:
print(f'You passed a {value!r}.')
>>> what_was_passed("abc")
You passed a 'abc'.
>>> what_was_passed(object())
You passed a <object object at 0x0000027AF6AD88C0>.
>>> what_was_passed()
Nothing was passed.
>>> what_was_passed(None)
You passed a None.
python的比较,我们必须了解is关键字python的 is运算符用于检查两个值 是否引用内存相同的确切对象。
将python对象想象位空间中漂浮的盒子,变量,数组索引等被命名位指向这些对象的箭头
而 object 的行为 == 被定义为比较 id,例如这样的类型东西可覆盖 ==
class object:
def __eq__(self, other):
return self is other
实际实现object 是用 C 编写的
x = [1, 2, 3]
y = [1, 2, 3]
x is y
False
x == y
True
我们还没有看过all或者zip还没有看过,但这一切都是为了确保所有给定的列表索引都是相等的。
同样,集合是无序的,所以即使它们的位置也不重要,只有它们的“存在” Python 有了hashes的概念。
任何一段数据的“散列”指的是一个看起来非常随机的预先计算的值,但它可以用来识别那段数据。
6 哈希
哈希有两个特定的属性:
相同的数据将始终具有相同的哈希值。
即使是非常轻微地更改数据,也会以完全不同的哈希值返回。
这意味着如果两个值具有相同的哈希值,那么它们很可能 * 也具有相同的值。
比较哈希是检查“存在”的一种非常快速的方法。这是字典和集合用来立即在其中查找值的方法:
>>> hash(42) == hash(42.0) == hash(42+0j)
True
不可变的容器对象,例如字符串(字符串是字符串的序列)、元组和frozensets,通过组合它们的项目的哈希来生成它们的哈希。
这允许您通过组合函数来为您的类创建自定义哈希hash函数
class Car:
def __init__(self, color, wheels=4):
self.color = color
self.wheels = wheels
def __hash__(self):
return hash((self.color, self.wheels))
7 dir 和 vars 一切都是字典对象
所有内容都存储在字典中,vars方法公开了存储在对象和类的变量 一个函数的 的vars方法
>>> vars(what_was_passed)
{}
一个类的vars方法
c = C(x=3)
>>> vars(C)
mappingproxy({'__module__': '__main__',
'some_cons': 42,
'__init__': <function C.__init_
_ at 0x0000027AF72F4940>,
'mth': <function C.mth at 0x0000027AF72F49D0>,
'__dict__': <at
tribute '__dict__' of 'C' objects>,
'__weakref__': <attribute '__weakref__' of 'C' objects>,
'__doc__': None})
>>> vars(c)
{'x': 3}
c.__class__ # 来自继承
<class '__main__.C'>
方法(mth和__init__)实际上作为函数存储在类的字典中 ,函数本身的代码不会因每个对象而改变,只有传递给它的变量会改变。
>>> class C:
... def function(self, x):
... print(f'self={self}, x={x}')
>>> c = C()
>>> C.function(c, 5)
self=<__main__.C object at 0x7f90762461f0>, x=5
>>> c.function(5)
self=<__main__.C object at 0x7f90762461f0>, x=5
查看objects的所有属性:
>>> "__class__" in vars(object)
True
>>> vars(object).keys()
dict_keys(['__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__dela
ttr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__
', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__',
'__sizeof__', '__dir__', '__class__', '__doc__'])
“方法解析顺序”是如何工作的。简称 MRO, 这是一个对象继承属性和方法的类的列表。
>>> class A:
... def __init__(self):
... self.x = 'x'
... self.y = 'y'
...
>>> class B(A):
... def __init__(self):
... self.z = 'z'
...
>>> a = A()
>>> b = B()
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> dir(b)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'x', 'y', 'z']
>>> set(dir(b)) - set(dir(a)) # all values in dir(b) that are not in dir(a)
{'z'}
>>> vars(b).keys()
dict_keys(['z'])
>>> set(dir(a)) - set(dir(object))
{'x', 'y'}
>>> vars(a).keys()
dict_keys(['x', 'y'])
因此,每一级继承都会将较新的方法添加到dir列表中,并dir在子类上显示在其方法解析顺序中找到的所有方法。
这就是 Python 在 REPL 中建议方法完成的方式:
class A:
x = 'x'
class B(A):
y = 'y'
b = B()
b. # 两次 tab 键 。???
b.x b.y # 自动
slots 它只允许其中定义的内容 被类实现。 如果对比 go 的接口,可以类型理解,在go接口中如果没有实现,则编译检查报错。 在python中如果实现超过 slots 定义,则报错。
这是 Python 具有的一种奇怪/有趣的行为:
object 默认具有 slots, 也支持自定义内容。
>>> x = object()
>>> x.f = 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'f'
>>> class A:
... x = 1
...
>>> a = A()
>>> a.f = 5
这就是hash用武之地。首先,让我复制我自己的类list和object在我自己的类中显示的行为:
>>> class C:
... __slots__ = ()
...
>>> c = C()
>>> c.foo = 5
AttributeError: 'C' object has no attribute 'foo'
python的存储数据方式,
字典 更多使用内存,
列表结构,本质上类型python的元组,结构具有固定大小,内存更少。
这两种方式通过两个对象属性 dict 和 slots
通常所有实例属性 self.foo 都存储在__dict__字典
除非定义 __slots__属性,这样对象只能具有恒定的指定的属性
定义了 __slots__将不会加载 dict
如下 list 的内置函数:
vars(list)
mappingproxy({'__repr__': <slot wrapper '__repr__' of 'list' objects>, '__hash__': None, '__getattribute__': <slot wrapper '__getattribute__' of 'list' objects>, '__lt__': <slot wrapper '__lt__' of 'list' objects>, ...)
__repr__:<slot wrapper '__repr__' of 'list' objects>
清晰一些的显示 list 结构:
__hash__:None
__getattribute__:<slot wrapper '__getattribute__' of 'list' objects>
__lt__:<slot wrapper '__lt__' of 'list' objects>
__le__:<slot wrapper '__le__' of 'list' objects>
__eq__:<slot wrapper '__eq__' of 'list' objects>
__ne__:<slot wrapper '__ne__' of 'list' objects>
__gt__:<slot wrapper '__gt__' of 'list' objects>
__ge__:<slot wrapper '__ge__' of 'list' objects>
__iter__:<slot wrapper '__iter__' of 'list' objects>
__init__:<slot wrapper '__init__' of 'list' objects>
__len__:<slot wrapper '__len__' of 'list' objects>
__getitem__:<method '__getitem__' of 'list' objects>
__setitem__:<slot wrapper '__setitem__' of 'list' objects>
__delitem__:<slot wrapper '__delitem__' of 'list' objects>
__add__:<slot wrapper '__add__' of 'list' objects>
__mul__:<slot wrapper '__mul__' of 'list' objects>
__rmul__:<slot wrapper '__rmul__' of 'list' objects>
__contains__:<slot wrapper '__contains__' of 'list' objects>
__iadd__:<slot wrapper '__iadd__' of 'list' objects>
__imul__:<slot wrapper '__imul__' of 'list' objects>
__new__:<built-in method __new__ of type object at 0x00007FFE87DA1AF0>
__reversed__:<method '__reversed__' of 'list' objects>
__sizeof__:<method '__sizeof__' of 'list' objects>
clear:<method 'clear' of 'list' objects>
copy:<method 'copy' of 'list' objects>
append:<method 'append' of 'list' objects>
insert:<method 'insert' of 'list' objects>
extend:<method 'extend' of 'list' objects>
pop:<method 'pop' of 'list' objects>
remove:<method 'remove' of 'list' objects>
index:<method 'index' of 'list' objects>
count:<method 'count' of 'list' objects>
reverse:<method 'reverse' of 'list' objects>
sort:<method 'sort' of 'list' objects>
__class_getitem__:<method '__class_getitem__' of 'list' objects>
__doc__:Built-in mutable sequence.
字典dict 结构:
__repr__:<slot wrapper '__repr__' of 'dict' objects>
__hash__:None
__getattribute__:<slot wrapper '__getattribute__' of 'dict' objects>
__lt__:<slot wrapper '__lt__' of 'dict' objects>
__le__:<slot wrapper '__le__' of 'dict' objects>
__eq__:<slot wrapper '__eq__' of 'dict' objects>
__ne__:<slot wrapper '__ne__' of 'dict' objects>
__gt__:<slot wrapper '__gt__' of 'dict' objects>
__ge__:<slot wrapper '__ge__' of 'dict' objects>
__iter__:<slot wrapper '__iter__' of 'dict' objects>
__init__:<slot wrapper '__init__' of 'dict' objects>
__or__:<slot wrapper '__or__' of 'dict' objects>
__ror__:<slot wrapper '__ror__' of 'dict' objects>
__ior__:<slot wrapper '__ior__' of 'dict' objects>
__len__:<slot wrapper '__len__' of 'dict' objects>
__getitem__:<method '__getitem__' of 'dict' objects>
__setitem__:<slot wrapper '__setitem__' of 'dict' objects>
__delitem__:<slot wrapper '__delitem__' of 'dict' objects>
__contains__:<method '__contains__' of 'dict' objects>
__new__:<built-in method __new__ of type object at 0x00007FFE87D988B0>
__sizeof__:<method '__sizeof__' of 'dict' objects>
get:<method 'get' of 'dict' objects>
setdefault:<method 'setdefault' of 'dict' objects>
pop:<method 'pop' of 'dict' objects>
popitem:<method 'popitem' of 'dict' objects>
keys:<method 'keys' of 'dict' objects>
items:<method 'items' of 'dict' objects>
values:<method 'values' of 'dict' objects>
update:<method 'update' of 'dict' objects>
fromkeys:<method 'fromkeys' of 'dict' objects>
clear:<method 'clear' of 'dict' objects>
copy:<method 'copy' of 'dict' objects>
__reversed__:<method '__reversed__' of 'dict' objects>
__class_getitem__:<method '__class_getitem__' of 'dict' objects>
__doc__:dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
(key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
d = {}
for k, v in iterable:
d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list. For example: dict(one=1, two=2)
小结
天高任鸟飞,更多的新内容python社区也在持续添加。感兴趣的朋友请关注专栏。
创建对象使用type 基础元类时,通过指定不同的内置函数的原语,可以实现很多特殊的功能,适应不同的场景,比如在某些会话调用中,惰性计算的例子。这在将来章节我们可以谈到。
- 点赞
- 收藏
- 关注作者
评论(0)