Python 小知识点

Python 小知识点

这里记录每次看到的一些容易疏忽的知识点

以后会实时更新

1. 使用 __name__ == ‘__main__’ 测试 module

所有的 module 都有内建的属性 __name__ 。该属性的值取决于我们怎样使用该 module。

2. 赋值

2.1 tuple – and list-unpacking assignment

When a tuple or list is on the left side of the “=”, Python pairs objects on the right side with targets on the left by position and assigns them from left to right one at a time.

注意: tuple 赋值时,我们可以删去圆括号,比如:

一个比较常见的场景是: 返回多个值的函数,我们最后只需要只需要返回包含所有值的 tuple 即可,而这在 C/C++ 是不可能的,只能用结构体或者参数指针,引用参数来解决这个问题。

trick:

由于 Python 会创建一个临时 tuple 保存右侧所有变量的原始值,因此我们可以用这个方法来交换两个变量的值,而无须自己创建临时变量存储

下面有个很好玩的例子,来体现这一点

2.2 sequence assignments

generalized from the tuple and list assignment, we can assign any sequence of values to any sequence of names

2.3 extended sequence unpacking

a single starred name , *X can be used in the assignment target in order to specify a more general matching against the sequence – the starred name is assigned a list, which collects all items in the sequence not assigned to other names.

2.4 Augmented Assignments

Python 也支持 X += Y 这样的写法

除了可以写更少的代码,这种写法也会自动选择优化技术:

For objects that support in-place changes, the augmented forms automatically perform in-place change operations instead of slower copies.

Concatenation operations must create a new object, so generally run slower than the in-place equivalent

可以看下这个例子:

3. generic operation VS methods

在学习 Pythons 时,可能会对一件事情感到疑惑,什么时候用 generic operation,什么时候用 methods

比如,我们要获得 字符串的长度,会用 :

如果我们想对 该字符串分割,则会:

请记住下面这句话:

As a rule of thumb, Python’s toolset is layered: generic operations that span multiple types show up as build-in functions or expression (e.g., len(X), X[0]), but type-specific operations are method calls (e.g., aString.upper())

4. 查阅某个类的方法 – dir()

dir() 可以帮助你了解传入参数对应的对象的所有可用属性 (attribute),包括所有的 method (它们是 function attribute)

然后我们可以使用 help() 来查阅 该函数的文档 (docstring)

5. 字符串的艺术

  1. 多行字符串 – triple quote (single or double)

    但请注意, don’t put you comment above or below the quoted text.

  2. 在 quote 前面加入 r 表示 raw string literal, 不会对转义字符进行解析,比如 r'C:\text\new')
    注:
    r"...\: 不是一个合法的 string literal – a raw string cannot end in an odd number if backslashes.
    补救方法

    • r'1\nb\tc\\'[:-1]
    • r'1\nb\tc'+'\\'
    • 采用常规描述: 1\\nb\\tc\\
  3. 在字符串中 \x 表示 16进制 8 bits 数 (比如 \xe6 ),\u 表示 utf-16 位 和 utf 64位
  4. There are three string types:
    • str used for Unicode text (including ASCII): sequences of Unicode code points
      length of str is the number of characters instead of bytes in strings.

    • bytes used for binary data (including encoded text)

    • bytearray is a mutable variant of bytes

    Files work in two modes: text, which represents content as str and implements Unicode encoding, and binary, which deals in raw bytes and does no data translation.

    字符串 quote 前面加入 b 表示 raw byte values (包括 多媒体数据和加密文本),显示的是没有可读性的二进制数据 ,按字节分割,16进制显示,比如 b'sp\xc3\x84m'
    通常见到的 encode() 函数会将普通字符串编码成raw byte values,存储到文本中,我们可以指定编码格式,比如

    decode() 用于将得到的二进制数据反解码成具有可读性的文本
    :

    • Unicode 是 字符集 ,为每一个字符分配一个唯一的 ID (学名为 码位/ 码点/ Code Point)
    • Utf-8 是 编码规则 , 将 码位 转换为字符序列的规则 (编码 encoding / 解码 decoding ),并不是简单地直接将码位变为二进制

    广义的 Unicode 是一个标准,定义了一个字符集以及一系列的编码规则,即 Unicode 字符集,和 UTF-8, UTF-16, UTF-32 等等编码
    Unicode 字符集为每一个字符分配一个码位,例如 [知] 的码位是 30693, 记为 U+77E5,(30693 的 十六进制为 0x77E5)
    Utf-8 是一套以 8 位为一个编码单位的可变长编码。会将一个码位编码为 1 到 4 个字节:

    U+ 0000 ~ U+ 007F: 0XXXXXXX
    U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
    U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
    U+10000 ~ U+1FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

    在 Python build-in function 中,有两个函数可以查看每个字符对应的 Unicode 码 (码位)

    • ord() – given a string representing one Unicode character, return an integer representing the Unicode code point (码位) of the character
    • chr(i) – return the string representing a character whose Unicode code point is the integer i

    tip:
    如果想得到一个字符串 对应的 Unicode 码位,除了 用 for 循环,还可以用 map(ord, S)

  5. S[:-1] 这种方法可以 fetches all but the last item
    S[:] 可以用于字符串拷贝, top-level copy, this isn’t very useful for immutable objects like strings, but it comes in handy for objects that may by changed in place, such as lists.
    S[::-1] : negative stride can reverse the sequence.

  6. formatting expression syntax
    %[(keyname)][flags][width][.precision]typecide

    • provide a key name for indexing the dictionary used on the right side of the expression
    • List flags that specify things like left justification (-), numeric sign (+), a blank before positive number and a for negatives (a space), and zero fills (0)
    • Give a total minimum field width for the substituted text (注意是最短字段长度)
    • Set the number of digits (precision) to display after a decimal point for floating-point numbers

    note: when minimum width or precision are not known until runtime, you can use a computed width and precision by specifying them with a * in the format string to force their values to be taken from the next item in the inputs to the right of the % operator – the 4 in the tuple here gives precision:

6. set 的一些注意点

  1. set 是 一个类

  2. set() 会实例化一个类 – set,其实并不是函数

  3. 空的 {} 新建的是一个dict 类型,不是set 类型;
    {} 内部如果存在数据,则返回的是set 类型

    这是 python2 的遗留问题
    note: tuple 如果只含有一个 item,初始化需要在末尾加一个 trailing comma, 比如 (1,)

  4. set 添加变量的函数

    • update() : 参数也是一个set 类型
    • add() : 只能添加 immutable (hashable) object
  5. set 删除变量的函数
    • remove() 删除单个值,但如果要删除的值不存在,会出现KeyError 异常
    • discard() 删除单个值,如果要删除的值不存在,不做任何处理
  6. set 是无序的,因此两个 set 比较时,不会考虑元素的次序
  7. set 支持的运算: - (集合的差), | (或运算),& (与 运算), >, < (判断 子集 和 父集)
  8. set 支持 set comprehension construct

    在 python iteration 会进一步介绍

7. docstring – 函数的使用说明

Python 每一个函数都有一个 __doc__ 属性,用于该函数的使用文档,类型是字符串,简写为 docstring

注意:

  1. 3个引号 ''' 表示多行字符串,头部和尾部''' 之间的部分都是单个字符串
  2. 如果一个函数由记录文档,那么它必须是函数内部第一件要做的事,也就是说,函数声明的下一行就开始写文档

8. int(), float()

int() 的用途: 将许多类型转换为 int object

  • string -> int, e.g. : int('12')

  • float -> int, e.g.: int(-1.34) (truncate decimals)

  • string of hex(16进制), oct (8进制), bin(2进制) -> int,
    e.g.: int('0xF3', 16) , int('0o34', 8), int('0b10', 2)

float() 的用途: 将许多类型转换为 float object

  • string -> float
  • int -> float

9. * for tuple, ** for dict

说白了, * 将 tuple 每个元素都解包 (unpack) 出来,作为单独的函数的参数,** 将 dict 的每一对 item 都解包出来,作为单独的 key = value 形式的参数

* before an object of tuple type is used to unpack tuple’s items into individual function arguments.

** is used to unpacks a dictionary of keys and values into individual “name=value” keyword arguments so they can be referenced by name in the format string

9.1 function arguments order

函数定义时,参数设计顺序:

  1. normal arguments (name)
  2. default arguments (name = value, 这里等号表示默认值)
  3. *name form (build a collection)
  4. **name form

python 参数传递

  1. assign nonkeyword arguments by position
    先按次序传递

  2. assign keyword arguments by matching names
    按 key = value 传递,这里等号表示按键值赋值

  3. assign extra nonkeyword arguments to *name tuple
    多余的 value 统一归到 name tuple

  4. assign extra keyword arguments to **name dictionary
    多余的 key = value 统一归到 name dictionary

  5. assign default values to unassigned arguments in header
    未赋值的按默认值赋值

下面是参数传递的例子, pargs 搜集到了 2, 3 , 而 kargs 分到了 x=1, y=2

请牢记下面这句话:

the */** starred-argument syntax:
in the function header , it collects any number of arguments
while in the function call, it unpacks any number of arguments
In both, one start * means positional (tuple), and two stars ** means keywords (dictionary)

极端一点的例子:

10. slice assignment VS index assignment

slice assignment is best thought of as a combination of two steps:

  1. Deletion. The slice you specify to the left of the = is deleted
  2. Insertion. The new items contained in the iterable object to the right of the = are inserted into the list on the left, at the place where the old slice was deleted.

请注意 slice assignment (切片赋值) 和 assign to a single index (单个索引赋值)

slice assignment is a deletion plus an insertion (先删除后插入), so we can delete a section of a list by assigning an empty list to a slice (L[i:j]=[]); Python deletes the slice named on the left, and then inserts nothing.

But !!!!

Assigning an empty list to an index, on the other hand, just stores a reference to the empty list object in the simplified slot, rather than deleting an item 。说白了,单索引赋值就是直接将= 右边 object 拷贝赋值到 list 的指定索引位置

11. Dictionary Indexing

除了可以使用 if 进行分支选择,这里有一个特别的技巧

我们用 dictionary 结构,每个键值对应一个 lambda 表达式。通过键值索引可以获得一个函数,然后使用 () 表示调用该函数。这样就可以实现同样效果的分支代码执行。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d 博主赞过: