python skill
  1. python 查看变量大小

    sys.``getsizeof(object[, default])

  2. 解包

    1
    2
    3
    4
    5
    a, *mylist = 1,2,3,4,5
    *arv = [1, 4, 5] //SyntaxError: starred assignment target must be in a list or tuple
    *arv, = [1, 4, 5] //相当于复制
    ref:https://stackoverflow.com/questions/43190992/understanding-x-lst
    不过python3,copy方法更加的通用,毕竟x = p[:],只能用在可以切片的元素上。
  3. python -c “print(‘Hello World’)”. //python 命令行,直接执行python代码

    Python -m http.server // -m mod : run library module as a script (terminates option list)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /tmp/test/run.py 内容如下:
    #!/bin/env python
    import sys
    print(sys.path)

    当前路径在/tmp下
    执行python3 ./test/run.py,会发现/tmp/test/run 被加入到sys.path中。
    执行python -m test.run,会发现 ‘’, 一个空的字符串被加入到sys.path中。
    Note that the empty '' entry means the current directory。
    所以这个是python -m 与python 直接执行的第一个区别。

    因此,python -m http.server, 这条命令,就可以理解为:python解释器,在sys.path 中找到http模块的server.py,进行运行。
  4. python的私有化

    单一个下划线开头的变量,如_var,类对象/子类都可以访问到,但是from somemodule import * 禁止导入。

    双下划线开头的变量,如__var,类对象/子类都访问不到。from somemodule import * 禁止导入。

    1
    2
    3
    4
    //特别注意一下这种,是可以访问到的
    import somemodule
    print(somemodule._var) //这种模式是可以访问到的
    print(somemodule.__var) //这种模式是可以访问到的
  5. 字典

    首先,字典和列表都是可变变量。

    字典是无序的,查找和插入的时间,不会随着数据增加而增加,但是占用空间大。

    而列表时有序的,查找和插入的时间,随着数据增加而增加,但是空间浪费少。字典的key必须是不可变对象,因为dict存储或是查找时, 都是通过对key进行哈希算法计算,得出value所存储的位置。如果key也可以变,那就乱套了。

    1
    2
    3
    4
    5
    >>> key = [1, 2, 3]
    >>> d[key] = 'a list'
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
  6. method方法 & function函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // function 指的是普通的函数。比如:
    In [21]: def hello():
    ...: pass

    In [22]: hello
    Out[22]: <function __main__.hello()>



    // method 指的是实例对象里的方法
    In [23]: class A(object):
    ...: def __init__(self):
    ...: pass
    ...:
    ...: def echo():
    ...: print('b')

    In [24]: A.__init__
    Out[24]: <function __main__.A.__init__(self)>

    In [25]: a = A()

    In [26]: a.echo
    Out[26]: <bound method A.echo of <__main__.A object at 0x1121551d0>>
![image-20200606144203893](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfikcyn7ugj31e20u01kx.jpg)
  1. 精度问题,是的,javascript也有这个问题,原因是小数通过二进制保存,巴拉巴拉的。。。 😁

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    In [10]: x = 0.1
    In [11]: y = 0.2
    In [12]: z = x + y
    In [13]: z
    Out[13]: 0.30000000000000004

    // --即使使用float类型,仍然有同样的问题--
    // 矫正一下,摆脱 0.1 本来就是浮点型啊。我当时是在梦游吗? 写的什么鬼
    In [23]: x = float('0.1')
    In [24]: y = float('0.2')
    In [25]: z = x + y
    In [26]: z
    Out[26]: 0.30000000000000004


    // 通过decimal解决
    from decimal import Decimal
    x = Decimal('0.1') + Decimal('0.4') //此处参数是字符串哦。
    print(x)

    //用==来对比浮点数时,可能出现意料外的事,这时候,用可以用<0.000001来比对。
    a = 0.1
    b = 0.2
    c = 0.3
    print(a + b == c)
    print(abs(a + b - c) < 0.000001)

    结论:如果需要精度非常高的,decimal 是一个选项, 但是日常总是免不了遇到浮点型的数据操作。面对这种日常场景如何处理呢。

    • python的// 返回的总是小数,而 / 返回的就只有整数。所以拿到//的返回值,做一些判断的时候,要多加注意。
  1. Python 枚举

    刷TypeScript的时候,遇到了枚举类型。我突然意识到Python中,基础的数据类型中,没有枚举。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    // enum 只有在python v3.4 才开始有
    In [3]: from enum import Enum

    In [4]: class Vip(Enum):
    ...: MONDAY = 1

    In [5]: class Vip(Enum):
    ...: MONDAY = 0
    ...: TUESDAY = 1
    ...: WEDNESDAY = 2

    In [6]: print(Vip.MONDAY)
    Vip.MONDAY

    In [7]: print(Vip(1))
    Vip.TUESDAY

    In [8]: print(type(Vip.MONDAY))
    <enum 'Vip'>

    In [9]: print(Vip.MONDAY.name)
    MONDAY

    In [10]: print(Vip.MONDAY.value)
    0

    // 从Enum派生出类后,直接引用。如果具体的值不重要,你可以使用 auto(),将为你选择适当的值。

    In [14]: class cat_type(Enum):
    ...: long_cat = enum.auto()
    ...: short_cat = enum.auto()

    In [15]: print(cat_type.long_cat)
    cat_type.long_cat

    In [16]: print(cat_type.long_cat.name)
    long_cat

    In [17]: print(cat_type.long_cat.value)
    1

    回顾logging模块里的CRITICAL,WARNNING,DEBUG,其实也并不是我猜测的enum类型。
    enum最大的特点在于不可更改,又带有枚举的特性。
  1. python 默认数据类型有数组吗?在Typescript中是有数组的。我起初以为list,没有二维数组。

    Note: Python does not have built-in support for Arrays, but Python Lists can be used instead.

    答案是没有,python的list并不是数组,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 如下list也是支持多维
In [11]: o = [1, 2, 3]
...: i = ['a', 'b', 'c']
...: z = [o, i]
...: print(z)
[[1, 2, 3], ['a', 'b', 'c']]

# 如下array模块的数组,必须是同一个类型
In [12]: import array as arr
...:
...: a = arr.array('d',[1,2,3,'a',5])
...: print(a)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-db567c5861b7> in <module>
1 import array as arr
2
----> 3 a = arr.array('d',[1,2,3,'a',5])
4 print(a)

TypeError: must be real number, not str

# Python 也带有array模块,但是并不支持二位数据组,
In [15]: import array as arr
...:
...: a = arr.array('d',[[1,2,3],[4,5,6]])
...: print(a)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-15-14dc313d3c9e> in <module>
1 import array as arr
2
----> 3 a = arr.array('d',[[1,2,3],[4,5,6]])
4 print(a)

TypeError: must be real number, not list

重点:list中的数据类型保存的是数据所存放的地址,简单的说就是指针,并非数据,这样保存一个list就太麻烦了,例如list1=[1,2,3,’a’]需要4个指针和四个数据,增加了存储和消耗cpu。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# numpy 会更灵活,也支持多维
In [1]: import numpy as np
...:
...: a = np.array([1, 2, 3, 4, 5])
...: b = np.array([[1, 2, 3], [4, 5, 6]])
...: c = list(a) # array到list的转换
...: print(a)
...: print(b)
...: print(c)
...:
[1 2 3 4 5]
[[1 2 3]
[4 5 6]]
[1, 2, 3, 4, 5]
  1. python 使用@property, 切记使用@property所使用的必须是收保护的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Student():
    def __init__(self, age, gender):
    self.age = age
    self.gender = gender

    @property
    def gender(self):
    return self.gender

    s = Student(age=14, gender='male')
    print(s.gender)
Author: Chandler Kwok
Link: http://yoursite.com/2020/05/30/python-skill/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.