|
| 1 | +## 💬 Python 语言基础 |
| 2 | + |
| 3 | +### 语言语义 |
| 4 | + |
| 5 | ++ Tab(或空格) 缩进 |
| 6 | + |
| 7 | + ```python |
| 8 | + for x in array: |
| 9 | + if x < pivot: |
| 10 | + less.append(x) |
| 11 | + else: |
| 12 | + greater.append(x) |
| 13 | + ``` |
| 14 | + |
| 15 | ++ 一切皆对象 |
| 16 | + |
| 17 | + 每一个数值、字符串、数据结构、函数、类、模块以及所有存在于 Python 解释器中的事物,都是 Python 对象。 |
| 18 | + |
| 19 | ++ 注释 |
| 20 | + |
| 21 | + 当行注释 |
| 22 | + |
| 23 | + ```python |
| 24 | + # 此行被注释 |
| 25 | + |
| 26 | + print("Hello World") # 当然也可以注释在语句后 |
| 27 | + ``` |
| 28 | + |
| 29 | + 多行注释 |
| 30 | + |
| 31 | + ```python |
| 32 | + ''' |
| 33 | + 多行注释,使用三个单引号 ' |
| 34 | + ''' |
| 35 | + |
| 36 | + """ |
| 37 | + 多行注释,也可使用三个双引号 " |
| 38 | + """ |
| 39 | + |
| 40 | + """ |
| 41 | + 当然,单引号和双引号不能混用! |
| 42 | + ''' |
| 43 | + ``` |
| 44 | +
|
| 45 | ++ 函数和对象方法的调用 |
| 46 | +
|
| 47 | + 调用函数,向函数括号里传递 0 或多个参数,通常会把返回值赋值给一个变量: |
| 48 | +
|
| 49 | + ```python |
| 50 | + result = f(x, y, z) |
| 51 | + g() |
| 52 | + ``` |
| 53 | +
|
| 54 | + 调用对象内部方法,使用点: |
| 55 | +
|
| 56 | + ```python |
| 57 | + obj.some_method(x, y, z) |
| 58 | +
|
| 59 | + # 函数传参既可以是位置参数也可以是关键字参数: |
| 60 | + result = f(a, b, c, d=5, e='foo') |
| 61 | + ``` |
| 62 | +
|
| 63 | ++ 变量和参数传递 |
| 64 | +
|
| 65 | + Python 中,对变量赋值时,你就创建了一个指向等号右边对象的引用,例如: |
| 66 | +
|
| 67 | + ```python |
| 68 | + # 变量 a,赋值一个列表 list |
| 69 | + a = [1, 2, 3] |
| 70 | +
|
| 71 | + # 现将 a 赋值给新变量 b |
| 72 | + b = a |
| 73 | +
|
| 74 | + ''' |
| 75 | + 某些语言中,这种赋值是值拷贝过程,即上述中是列表 [1,2,3] 赋值给了 b |
| 76 | + 而在 Python 中,是 a、b 指向了相同的对象 list[1,2,3] |
| 77 | + 可以验证如下: |
| 78 | + ''' |
| 79 | + b.append(4) |
| 80 | +
|
| 81 | + print(a) |
| 82 | + # 输出 [1, 2, 3, 4] |
| 83 | + ``` |
| 84 | +
|
| 85 | + Python 中有 *可更改(mutable)对象* 与 *不可更改(immutable)对象*。可更改类型有:list、dict;不可更改类型有:string、tuple、number |
| 86 | +
|
| 87 | + 在函数参数传递中,对于可更改对象,类似于 C++ 引用传递,对于不可更改类型,类似于 C++ 值传递: |
| 88 | +
|
| 89 | + ```python |
| 90 | + # 不可更改对象作为函数参数 |
| 91 | + def f1(value): |
| 92 | + value += 1 |
| 93 | + |
| 94 | + a = 10 |
| 95 | + f1(a) |
| 96 | + print(a) # 输出 10 |
| 97 | +
|
| 98 | +
|
| 99 | + # 可更改对象作为函数参数 |
| 100 | + def f2(some_list, element): |
| 101 | + some_list.append(element) |
| 102 | + |
| 103 | + data = [1, 2, 3] |
| 104 | + f2(data, 4) |
| 105 | + print(data) # 输出 [1, 2, 3, 4] |
| 106 | + ``` |
| 107 | +
|
| 108 | ++ 动态引用、强类型 |
| 109 | +
|
| 110 | + Python 中的对象引用并不涉及类型,这称为 *动态类型*: |
| 111 | +
|
| 112 | + ```python |
| 113 | + a = 5 |
| 114 | + pring(type(a)) # int |
| 115 | +
|
| 116 | + a = 'foo' |
| 117 | + print(type(a)) # str |
| 118 | + ``` |
| 119 | +
|
| 120 | + Python 是 *强类型语言*,这意味着所有的对象都拥有一个指定的类型(或类),隐式转换只在某些特定、明显的情况下发生: |
| 121 | +
|
| 122 | + ```python |
| 123 | + print('5' + 5) |
| 124 | + --------------------------------------------------------------------------- |
| 125 | + TypeError Traceback (most recent call last) |
| 126 | + <ipython-input-16-4dd8efb5fac1> in <module> |
| 127 | + ----> 1 '5' + 5 |
| 128 | +
|
| 129 | + TypeError: can only concatenate str (not "int") to str |
| 130 | + ``` |
| 131 | +
|
| 132 | + ```python |
| 133 | + a = 4.5 |
| 134 | + b = 2 |
| 135 | +
|
| 136 | + print('a is {0}, b is {1}'.format(type(a), type(b))) |
| 137 | + # 输出 a is <class 'float'>, b is <class 'int'> |
| 138 | + print(a / b) |
| 139 | + # 输出 2.25 |
| 140 | + print(type(a / b)) |
| 141 | + # 输出 <class 'float'> |
| 142 | + ``` |
| 143 | +
|
| 144 | + *isinstance* 函数可以检查一个对象是否是特定类型的实例: |
| 145 | +
|
| 146 | + ```python |
| 147 | + a = 5 |
| 148 | + print(isinstance(a, int)) |
| 149 | + # 输出 True |
| 150 | +
|
| 151 | + # 也可以接收一个元组,判断 对象 是否是其中类型之一 |
| 152 | + b = 4.5 |
| 153 | + print(isinstance(a, (int, float))) |
| 154 | + # 输出 True |
| 155 | + print(isinstance(b, (int, float))) |
| 156 | + # 输出 True |
| 157 | + ``` |
| 158 | +
|
| 159 | ++ 属性和方法 |
| 160 | +
|
| 161 | + Python 中对象通常都会有属性和方法,属性和方法都可以通过 `obj.attribute_name` 调用: |
| 162 | +
|
| 163 | + ```python |
| 164 | + In [1]: a = 'foo' |
| 165 | +
|
| 166 | + In [2]: a.<Tab> |
| 167 | + a.capitalize a.format ... |
| 168 | + ``` |
| 169 | +
|
| 170 | + 属性和方法也可通过 *getattr* 函数获得,这种通过变量名访问对象通常被称为“反射”: |
| 171 | +
|
| 172 | + ```python |
| 173 | + getattr(a, 'split') |
| 174 | + # <function str.split> |
| 175 | +
|
| 176 | + # 同类型还有 hasattr 和 setattr |
| 177 | + ``` |
| 178 | +
|
| 179 | ++ 鸭子类型 |
| 180 | +
|
| 181 | + 通常情况下,你并不关心某个对象的具体类型,而关心它是否拥有某个特殊的方法或行为。 |
| 182 | +
|
| 183 | + > “鸭子类型” 说法源于 “一个东西走起来像鸭子叫起来像鸭子,那它就是鸭子”。例如,你可以验证一个对象如果实现了迭代器协议,那么它一定是可迭代的(包含 \_\_iter\_\_ 魔术方法) |
| 184 | +
|
| 185 | + ```python |
| 186 | + def isiterable(obj): |
| 187 | + try: |
| 188 | + iter(obj) |
| 189 | + return True |
| 190 | + except TypeError: |
| 191 | + return False |
| 192 | +
|
| 193 | + # 对于绝大部分 Python 容器类型的对象,iter 函数都会返回 True |
| 194 | + isiterable('a string') |
| 195 | + # True |
| 196 | + isiterable([1, 2, 3]) |
| 197 | + # True |
| 198 | + isiterable(5) |
| 199 | + # False |
| 200 | +
|
| 201 | + # 常见的案例是先检查对象是否是一个列表(或一个 NumPy 数组) |
| 202 | + # 如果不是则转换为一个列表 |
| 203 | + if not isinstance(x, list) and isiterable(x): |
| 204 | + x = list(x) |
| 205 | + ``` |
| 206 | +
|
| 207 | ++ 导入模块 |
| 208 | +
|
| 209 | + Python 模块就是以 *.py* 为后缀并包含 Python 代码的文件。假设有以下模块: |
| 210 | +
|
| 211 | + ```python |
| 212 | + # some_module.py |
| 213 | + PI = 3.14159 |
| 214 | +
|
| 215 | + def f(x): |
| 216 | + return x + 2 |
| 217 | +
|
| 218 | + def g(a, b): |
| 219 | + return a + b |
| 220 | + ``` |
| 221 | +
|
| 222 | + 要导入模块中定义的变量和函数: |
| 223 | +
|
| 224 | + ```python |
| 225 | + import some_module |
| 226 | + |
| 227 | + result = some_module.f(5) |
| 228 | + pi = some_module.PI |
| 229 | + ``` |
| 230 | +
|
| 231 | + 或者: |
| 232 | +
|
| 233 | + ```python |
| 234 | + from some_module import f, g, PI |
| 235 | + |
| 236 | + result = g(5, PI) |
| 237 | + ``` |
| 238 | +
|
| 239 | + 也可用关键字 as,对导入内容更名: |
| 240 | +
|
| 241 | + ```python |
| 242 | + import some_module as sm |
| 243 | + from some_module import PI as pi, g as gf |
| 244 | +
|
| 245 | + r1 = sm.f(pi) |
| 246 | + r2 = gf(6, pi) |
| 247 | + ``` |
| 248 | +
|
| 249 | +<br> |
| 250 | +上述为 Python 中的一些基本特性,语法中的其他内容后续补充。 |
0 commit comments