diff --git a/new-test-20251106.txt b/new-test-20251106.txt new file mode 100644 index 000000000..2b7e60900 --- /dev/null +++ b/new-test-20251106.txt @@ -0,0 +1 @@ +1232 \ No newline at end of file diff --git "a/\345\255\246\344\271\240\347\254\224\350\256\260/Pyhton\345\270\270\347\224\250\346\250\241\345\235\227\345\217\212\345\207\275\346\225\260.ipynb" "b/\345\255\246\344\271\240\347\254\224\350\256\260/Pyhton\345\270\270\347\224\250\346\250\241\345\235\227\345\217\212\345\207\275\346\225\260.ipynb" new file mode 100644 index 000000000..8e156661f --- /dev/null +++ "b/\345\255\246\344\271\240\347\254\224\350\256\260/Pyhton\345\270\270\347\224\250\346\250\241\345\235\227\345\217\212\345\207\275\346\225\260.ipynb" @@ -0,0 +1,221 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "time 模块\n", + "print()\n", + "str()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### print()函数\n", + "\n", + "```python\n", + "print('a','b','c') # 输出a b c,因为print参数sep默认为空格' '\n", + "\n", + "i = 1\n", + "print('i=',i)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on built-in function print in module builtins:\n", + "\n", + "print(*args, sep=' ', end='\\n', file=None, flush=False)\n", + " Prints the values to a stream, or to sys.stdout by default.\n", + "\n", + " sep\n", + " string inserted between values, default a space.\n", + " end\n", + " string appended after the last value, default a newline.\n", + " file\n", + " a file-like object (stream); defaults to the current sys.stdout.\n", + " flush\n", + " whether to forcibly flush the stream.\n", + "\n" + ] + } + ], + "source": [ + "help(print)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 静态对象\n", + "静态对象一般指程序运行期间不会发生改变的对象,或者不需要实例化就可以直接使用的对象。包括:\n", + "- 模块:导入后可以直接使用的对象。\n", + "- 类的静态成员:无需实例化类即可访问的属性或方法。\n", + "- 不可变对象:值在创建后不会改变的对象。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 数学函数\n", + "| 函数 | 返回值 (描述) | 注意事项 |\n", + "|------|---------------|----------|\n", + "| abs(x) | 返回数字的绝对值,如 `abs(-10)` 返回 `10` | 内置函数,复数则返回其大小 |\n", + "| fabs(x) | 以浮点数形式返回数字的绝对值,如 `math.fabs(-10)` 返回 `10.0` | |\n", + "| ceil(x) | 返回数字的上入整数,如 `math.ceil(4.1)` 返回 `5` | `math.ceil(-4.1)` 返回 `-4` |\n", + "| floor(x) | 返回数字的下舍整数,如 `math.floor(4.9)` 返回 `4` | |\n", + "| exp(x) | 返回 e 的 x 次幂,如 `math.exp(1)` 返回 `2.718281828459045` | |\n", + "| log(x) | 如 `math.log(math.e)` 返回 `1.0`,`math.log(100,10)` 返回 `2.0` | |\n", + "| sqrt(x) | 返回数字 x 的平方根,如 `math.sqrt(100)` 返回 `10.0` | |\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### xx函数\n", + "| round(x [,n]) | 返回浮点数 x 的四舍五入值,如给出 n 值,则代表舍入到小数点后的位数。|不适合精度要求高的情况;round(2.675,2)会返回2.67,“四舍六入”|\n", + "| sqrt(x) | 返回数字 x 的平方根。|math.sqrt(100)返回10.0|" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 随机数函数\n", + "随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性。\n", + "需要先导入random模块\n", + "| 函数 | 描述 |注意事项|\n", + "|---------------|-------------|--------|\n", + "| `choice(seq)` | 从序列的元素中随机挑选一个元素,比如 `random.choice(range(10))`,从 0 到 9 中随机挑选一个整数。|seq可以是列表、元组或者字符串|\n", + "| `randrange([start,] stop [,step])` | 从指定范围内,按指定基数递增的集合中获取一个随机数,基数默认值为 1。||\n", + "| `random()` | 随机生成下一个实数,它在 `[0,1)` 范围内。 ||\n", + "| `seed([x])` | 改变随机数生成器的种子 `seed`。如果你不了解其原理,你不必特别去设定 `seed`,Python 会帮你选择 `seed`。 ||\n", + "| `shuffle(lst)`| 将序列的所有元素随机排序。|random.shuffle ()返回值是None|\n", + "| `uniform(x, y)` | 随机生成下一个实数,它在 `[x, y]` 范围内。|返回浮点数,闭区间|\n", + "\n", + "range()返回的是一个range对象,不是一个具体的列表或者元组。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 三角函数\n", + "\n", + "| 函数 | 描述 |\n", + "|---------------|--------------------------|\n", + "| `acos(x)` | 返回 `x` 的反余弦弧度值。 |\n", + "| `asin(x)` | 返回 `x` 的反正弦弧度值。 |\n", + "| `atan(x)` | 返回 `x` 的反正切弧度值。 |\n", + "| `atan2(y, x)` | 返回给定的 `x` 和 `y` 坐标值的反正切值。 |\n", + "| `cos(x)` | 返回 `x` 弧度的余弦值。 |\n", + "| `hypot(x, y)` | 返回欧几里德范数 `sqrt(x*x + y*y)`。 |\n", + "| `sin(x)` | 返回 `x` 弧度的正弦值。 |\n", + "| `tan(x)` | 返回 `x` 弧度的正切值。 |\n", + "| `degrees(x)` | 将弧度转换为角度,如 `degrees(math.pi/2)` 返回 `90.0`。 |\n", + "| `radians(x)` | 将角度转换为弧度。 |\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "range 函数:\n", + "Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## operator模块" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## map函数\n", + "把“同一个函数”依次作用到“可迭代对象的每一个元素”上,生成一个新的迭代器。\n", + "map(function,iterable)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on class map in module builtins:\n", + "\n", + "class map(object)\n", + " | map(func, *iterables) --> map object\n", + " |\n", + " | Make an iterator that computes the function using arguments from\n", + " | each of the iterables. Stops when the shortest iterable is exhausted.\n", + " |\n", + " | Methods defined here:\n", + " |\n", + " | __getattribute__(self, name, /)\n", + " | Return getattr(self, name).\n", + " |\n", + " | __iter__(self, /)\n", + " | Implement iter(self).\n", + " |\n", + " | __next__(self, /)\n", + " | Implement next(self).\n", + " |\n", + " | __reduce__(...)\n", + " | Return state information for pickling.\n", + " |\n", + " | ----------------------------------------------------------------------\n", + " | Static methods defined here:\n", + " |\n", + " | __new__(*args, **kwargs)\n", + " | Create and return a new object. See help(type) for accurate signature.\n", + "\n" + ] + } + ], + "source": [ + "help(map)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\345\255\246\344\271\240\347\254\224\350\256\260/Python\345\237\272\347\241\200\347\237\245\350\257\206.ipynb" "b/\345\255\246\344\271\240\347\254\224\350\256\260/Python\345\237\272\347\241\200\347\237\245\350\257\206.ipynb" new file mode 100644 index 000000000..7735c9f14 --- /dev/null +++ "b/\345\255\246\344\271\240\347\254\224\350\256\260/Python\345\237\272\347\241\200\347\237\245\350\257\206.ipynb" @@ -0,0 +1,2739 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "59f1ad7d", + "metadata": {}, + "source": [ + "> **记笔记的目的**: \n", + "> \n", + "> ★笔记不是“完整教程”,而是理解+易错点+示例+练习 \n", + "> \n", + "> 每一节:\n", + "> - “一句话总结(核心)”\n", + "> - “示例(能运行、最简单)”\n", + "> - “易错点(踩过的坑)”\n", + "> - “应用场景(什么时候用)”" + ] + }, + { + "cell_type": "markdown", + "id": "8a126022", + "metadata": {}, + "source": [ + "> 什么是“一句话总结”: \n", + "> - 它是什么\n", + "> - 为什么存在(解决什么问题?)\n", + "> - 什么时候用" + ] + }, + { + "cell_type": "markdown", + "id": "08c8aa7f", + "metadata": {}, + "source": [ + "> Python基础知识结构划分: \n", + "> - Python的特点\n", + "> - 环境搭建\n", + "> - 基础语法 \n", + "> - 变量 \n", + "> - 基本数据类型(数据结构) \n", + "> - 分支、循环结构\n", + "> - 函数和模块\n", + "> - 面向对象编程" + ] + }, + { + "cell_type": "markdown", + "id": "7b990156", + "metadata": {}, + "source": [ + "### Python的特点\n", + "1.大小写敏感。\n", + "2.对象(Object)、类(Class)、实例(Instance)三者的区别和联系\n", + "|名词|Python中的角色|举例|\n", + "|----|-----|----|\n", + "|对象(Object)|一切都是对象,包括数字、字符串、函数、类、模块|1、\"ABC\"、len、int|\n", + "|类(Class)|描述对象结构的模板,本质也是对象|int、list、dict|\n", + "|实例(Instance)|由类创建出来的对象|1 是 int 的实例|" + ] + }, + { + "cell_type": "markdown", + "id": "e43860bf", + "metadata": {}, + "source": [ + "### 环境搭建\n", + "为了能够在机器上运行Python,要处理的问题:\n", + "- 环境变量的问题 \n", + "- 二进制、八进制、十进制、十六进制\n", + "二进制的补码问题。\n", + "\n", + "- ASCII码、Unicode码\n", + "Python中所有的字符串都是Unicode字符串。\n", + "#### 命令行参数\n", + "交互模式中,最后被输出的表达式结果被赋值给变量_,例如:\n", + "```shell\n", + ">>> tax = 12.5 / 100\n", + ">>> price = 100.50\n", + ">>> price * tax\n", + "12.5625\n", + ">>> price + _\n", + "113.0625\n", + ">>> round(_, 2)\n", + "113.06\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "d9525ae6", + "metadata": {}, + "source": [ + "### Python基础语法\n", + "即为书写Python必须遵循的规则。\n", + "#### 标识符\n", + "标识符即为变量的命名,第一个字符必须以字母(a-z, A-Z)或下划线 _ ,其他部分由字母、数字和下划线组成。 \n", + "注意:标识符不能包含特殊字符(如 - ¥ $),不能使用数字开头,不能使用关键字。\n", + "##### 保留关键字\n", + "保留关键字在Python中有特定用处,不能作为标识符使用。\n", + "一旦用了,就会报错。\n", + "#### 注释\n", + "```\n", + "# 单行注释\n", + "# 第二个注释\n", + "\n", + "'''\n", + "第三行注释\n", + "第四行注释\n", + "'''\n", + "\n", + "\"\"\"\n", + "第五行注释\n", + "第六行注释\n", + "\"\"\"\n", + "```\n", + "#### 行与缩进\n", + "Python中用缩进表示代码块,而不是大括号`{}`。 \n", + "Python中一条语句很长,可以用反斜杠`\\`来实现换行。\n", + "```\n", + "total = item_one + \\\n", + " item_two + \\\n", + " item_three\n", + "``` \n", + "Python中同一行也可以有多个语句,用分号;分隔。 \n", + "在类或函数之间一般会留一个空行,便于日后的维护和重构。 \n", + "当写示例时,可以使用pass这个占位语句,表示什么都不做,以避免语法错误。\n", + "\n", + "#### 常用基本功能\n", + "1.接收用户用户输入,`str1=input()` \n", + "接收到的str1类型为string,还是`` \n", + "2.导入模块,用import与from...import \n", + "导入模块后,Python要知道使用的函数、类、变量来自哪个模块。 \n", + "`from...import`直接引入目标名称,调用更短,但是容易发生命名冲突。\n", + "`from...import *`会导入模块总的所有函数、变量,除了_开头的名字,但是会污染当前代码的命名空间。 \n", + "3.print格式化输出 \n", + "print()默认输出是带换行符的,即其中参数end默认值为'\\n'。\n", + "\n", + "#### 变量\n", + "1.Python中所有变量都是“名字→对象”的引用(变量存的是对象的地址)。 \n", + "变量没有类型,只有对象有类型。变量本质上等同于“自动管理内存的安全指针”。 \n", + "\n", + "2.一般说的变量类型指的是“变量当前指向的对象的类型”。\n", + "\n", + "3.衍生问题: \n", + "(1)如果变量存的是内存的地址,那么为什么print(变量)会返回对象的值? \n", + "print()调用的是变量所指向对象的`__str__()、__repr__()`方法,而不是打印地址。 \n", + "如果要打印地址,可以用print(id(a))返回变量a在内存中的地址id。 \n", + "(2)`a=1`和`a+1`中,变量a是地址,那为什么可以计算a+1? \n", + "先找到变量a指向的对象(1),调用该对象的__add__()方法(a.__add__(1))生成一个新的对象(2),然后把这个新的对象返回。原先的a和1都不会被修改。 \n", + "如果是`a=a+1`呢,这时候a引用的对象会变成2。 \n", + "(3)不可变对象(int,str,tuple)不能改,只能换对象; \n", + "可变对象(list,dict,set)能改,引用不变。 \n", + "不可变对象不允许修改内部值,修改只能创新新对象,旧对象如果无人引用则会被自动回收。 或者用del语句删除? \n", + "```python\n", + "a = 10 # int类型不可变\n", + "b = a\n", + "a = 20 # 修改a的值,不会影响b的值,10,20是两个独立的对象\n", + "# b 指的还是原先的整数10对象\n", + "\n", + "c = [1,2,3] # list类型可变\n", + "d = c\n", + "d.append(4) # 修改d的值,c的值也会变化,c和d是同个引用\n", + "```\n", + "(4)type(变量a)的时候,将变量a引用的对象作为参数传入内置函数type(),由type()查看该对象内部的`__class__属性`\n", + "\n", + "4.多变量赋值的问题:\n", + "`a=b=c=1`\n", + "`a,b,c=1,2,'runoob'`\n", + "\n", + "5.调换两个变量的值\n", + "`a,b=b,a`" + ] + }, + { + "cell_type": "markdown", + "id": "828e1f34", + "metadata": {}, + "source": [ + "### 数据类型\n", + "#### 数据类型简介\n", + "1.常见数据类型:\n", + "- Number(数字、数值):包含int、float、bool、complex(复数,例如4+3j)\n", + "- String(字符串)\n", + "- bool(布尔类型)\n", + "- List(列表)\n", + "- Tuple(元组)\n", + "- Set(集合)\n", + "- Dictionary(字典) \n", + "\n", + "2.数据类型分类可以按照是否可变,划分为: \n", + "不可变数据类型:Number、String、Tuple \n", + "可变数据类型:List、Dictionary、Set\n", + "\n", + "3.判断数据类型 \n", + "(1)type(obj)用来查对象的实际类型(class),例如`type(a)`,isinstance()用来判断对象(实例)是不是某个类型(或其子类)的实例,例如`isinstance(a,int)` \n", + "(2)区别:type()严格匹配类型,不考虑继承;isinstance()会考虑继承关系。 \n", + "```python\n", + "class A:pass # pass占位语句\n", + "class B(A):pass\n", + "\n", + "b = B()\n", + "print(type(b) is B) # True\n", + "print(type(b) is A) # False\n", + "print(isinstance(b,B)) # True\n", + "print(isinstance(b,A)) # True\n", + "print(issubclass(B,A)) # 判断类的继承关系,True\n", + "```\n", + "(3)特殊情况:\n", + "- `type(a) == int`和`type(a) is int`有什么区别? \n", + "`==` 是比较两个对象的“值”是否相等,不推荐,原因在==依赖类的`__eq__`,不是很严格; \n", + "`is` 是判断两个对象是否是“同一个对象”(id一致),推荐。\n", + "补充说明:int在Python中也是一个对象(类对象)\n", + "- `type(A)`返回的是啥?\n", + "返回type,类也是对象,Python中所有类的类型都是type\n", + "- `isinstance(B,A)`为啥是False?\n", + "`isinstance()`是用于判断实例是否属于某个类或者某个父类。\n", + "如果要判断两个类的继承关系,可以用`issubclass()`\n", + "\n", + "\n", + "#### 各个数据类型介绍与使用\n", + "##### 数字\n", + "1.数字注意事项:\n", + "数字是不可变类型。\n", + "\n", + "2.数字运算 \n", + "常规运算(加减乘除),除法或者混合运算时(包含浮点数和整数)运算结果一定为浮点数 \n", + "特殊运算:取余(%)、整除(//)、乘方(**) \n", + "`10%3`返回余数1 \n", + "`10//3`返回整数3,即10按照3来分,可以分成3个整份 \n", + "`10**3`返回1000 `4**0.5`返回2.0 \n", + "\n", + "3.运算符\n", + "注意事项:\n", + "(1)//取整是向小的方向取整数,例如9//2等于4,-9//2等于-5\n", + "(2):=海象运算符,用于在表达式中同时进行赋值,并返回赋值的值。Python3.8版本新增。\n", + "用法举例:\n", + "```python\n", + "#传统写法\n", + "n = 10\n", + "if n > 5:\n", + " print(n)\n", + "#使用海象运算符\n", + "if (n:=10) > 5: # 现把n赋值为10,再返回这个赋值结果\n", + " print(n)\n", + "```\n", + "(3)位运算符\n", + "位运算符把数字看做二进制来进行计算。\n", + "```python\n", + "a = 60\n", + "print(f'{a:08b}') # a的二进制数为 00111100\n", + "b = 13\n", + "print(f'{b:08b}') # b的二进制数为 00001101\n", + "\n", + "# & 按位与:两个对应位置都是1,则结果位为1,否则为0\n", + "print(a&b) #输出12 # a&b为 00001100\n", + "\n", + "# | 按位或:两个对应位置有一个是1,则结果位为1,否则为0\n", + "print(a|b) #输出61 # a|b为 00111101\n", + "\n", + "# ^ 按位异或:两个对应位置不同时,结果为1,否则为0\n", + "print(a^b) #输出49 # a|b为 00110001\n", + "\n", + "# ~ 按位取反:把0变成1,把1变成0\n", + "print(~a) #输出-61 # ~a为 -0111101?\n", + "\n", + "# << 左移动若干位\n", + "print(a<<2) #输出240,相当于放大了2的2次方倍 # <> 左移动若干位\n", + "print(a>>2) #输出15,相当于缩小了2的2次方倍 # <>`、`<<` | 右移、左移 |\n", + "| `&` | 按位与 |\n", + "| `^`、`\\|` | 按位异或、按位或 |\n", + "| `<=`、`<`、`>`、`>=` | 小于等于、小于、大于、大于等于 |\n", + "| `==`、`!=` | 等于、不等于 |\n", + "| `is`、`is not` | 身份运算符 |\n", + "| `in`、`not in` | 成员运算符 |\n", + "| `not`、`or`、`and` | 逻辑运算符 |\n", + "| `=`、`+=`、`-=`、`*=`、`/=`、`%=`、`//=`、`**=`、`&=`、`\\|=`、`^=`、`>>=`、`<<=` | 赋值运算符|\n", + "\n", + "补充说明:\n", + "not是小写。\n", + "逻辑运算符有阻断。\n", + "\n", + "2.数值不同表示形式 \n", + "(1)整数:十进制、二进制、八进制、十六进制 \n", + "```python\n", + "print(0o12) #八进制,0o或者0O\n", + "print(0b1010) #二进制,0b或者0B\n", + "print(0xA) #十六进制,0x或者0X\n", + "#十六进制的数A B C D E F 分别表示十进制中的 10 11 12 13 14 15\n", + "\n", + "# print()默认输出数值是转换为十进制显示。\n", + "print(oct(97)) #oct()十进制转为八进制字符串,输出0o141\n", + "print(hex(97)) #hex()十进制转为十六进制字符串,输出0x61\n", + "print(bin(97)) #bin()十进制转为二进制字符串,输出0b1100001\n", + "```\n", + "(2)浮点数:主要是显示格式(小数点后几位)的问题 \n", + "见字符串部分输出格式表 \n", + "(3)复数:复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b) 表示,复数的实部a和虚部b都是浮点型。如`3e+26j` " + ] + }, + { + "cell_type": "markdown", + "id": "3fb23002", + "metadata": {}, + "source": [ + "##### 字符串\n", + "1.字符串表示相关问题 \n", + "(1)反斜杠`\\`转义特殊字符,可以在字符串前面加一个`r`表示原始字符。\n", + "| 转义符 | 描述 | 示例代码 | 输出结果 |\n", + "|--------|----------|---------------|------------|\n", + "| `\\` | 续行符 | `print(\"line1 \\\\\\nline2\")` | `line1 line2` |\n", + "| `\\\\` | 反斜杠 | `print(\"\\\\\")` | `\\` |\n", + "| `\\'` | 单引号 | `print('\\'')` | `'` |\n", + "| `\\\"` | 双引号 | `print(\"\\\"\")` | `\"` |\n", + "| `\\a` | 响铃 | `print(\"\\a\")` | 响声 |\n", + "| `\\b` | 退格 | `print(\"Hello \\bWorld!\")` | `HelloWorld!` |\n", + "| `\\000` | 空字符 | `print(\"\\000\")` | 空(什么都不输出) |\n", + "| `\\n` | 换行 | `print(\"\\n\")` | 换行 |\n", + "| `\\v` | 纵表符 | `print(\"Hello\\vWorld!\")` | `Hello` 换行 `World!` |\n", + "| `\\t` | 横表符 | `print(\"Hello\\tWorld!\")` | `Hello World!` |\n", + "| `\\r` | 回车,将 `\\r` 后的内容移到字符串开头,并逐一替换开头部分的字符| `print(\"Hello\\rWorld!\")` | `World!` |\n", + "| `\\f` | 换页 | `print(\"Hello\\fWorld!\")` | `Hello` 换页 `World!` |\n", + "| `\\yyy` | 八进制 | `print(\"\\110\\145\")` | `He` |\n", + "| `\\xYY` | 十六进制,\\x开头,YY代表的字符 | `print(\"\\x48\\x65\")` | `He` |\n", + "| `\\other` | 普通字符 | 无特殊处理 | 无特殊处理 |\n", + "\n", + "例子:用\\r实现百分比进度\n", + "```python\n", + "import time\n", + "\n", + "for i in range(101): # 添加进度条图形,例如[#### ] 和百分比,例如30%\n", + " bar = '[' + '#' * (i) + ' ' * (100-i) + ']' # 100个\n", + " print(f'\\r{bar} {i:3}%',end='',flush=True) # flush选项的作用\n", + " time.sleep(0.02)\n", + "print()\n", + "```\n", + "(2)字符串的索引和截取:\n", + "区域是左闭右开,从0开始,-1为从末尾开始的位置。 \n", + "```python\n", + "str = 'Runoob'\n", + "print(str[0:-1]) # 'Runoob'\n", + "print(str[0]) # 'R'\n", + "print(str[2:5]) # 'noo'\n", + "print(str[2:]) # 'noob'\n", + "print(str[:2]) # 'Ru'\n", + "print(str[::-1]) # 'boonuR',默认步长为1,步长为-1时会反转\n", + "print(str[-1::-1]) # 'boonuR',默认步长为1,截取内的参数[start,end,step],当start为-1,end为空时,默认从右到左\n", + "```\n", + "\n", + "(3)字符串的运算符\n", + "```python\n", + "print(str * 2) # 'RunoobRunoob',*实现重复\n", + "print(str+'abc') # 'Runoobabc',+实现多个字符串连接\n", + "```\n", + "\n", + "(4)格式化输出:\n", + "有几种格式化方法\n", + "(a)用字符串格式符,例如%s(格式化字符串)、%d(格式化整数)\n", + "`print (\"我叫 %s 今年 %d 岁!\" % ('小明', 10))`\n", + "(b)用str.format(),用{}和:来代替以前的%\n", + "`{1} {0} {1}\".format(\"hello\", \"world\") # 设置指定位置`\n", + "(c)f-string,字面量格式化字符串,Python3.6之后的版本新增的格式化字符串\n", + "f后面跟着字符串,字符串中的表达式用大括号{}抱起来,会将表达式的结算结果带进输出的字符串里面\n", + "| 变量值 | 占位符 | 格式化结果 | 说明 |\n", + "| ----------- | ---------- | ------------| ---- |\n", + "| `3.1415926` | `{:.2f}` | `'3.14'` | 保留小数点后两位 |\n", + "| `3.1415926` | `{:+.2f}` | `'+3.14'` | 带符号保留小数点后两位 |\n", + "| `-1` | `{:+.2f}` | `'-1.00'` | 带符号保留小数点后两位 |\n", + "| `3.1415926` | `{:.0f}` | `'3'` | 不带小数 |\n", + "| `123` | `{:0>10d}` | `'0000000123'` | 左边补`0`,补够10位 |\n", + "| `123` | `{:x<10d}` | `'123xxxxxxx'` | 右边补`x` ,补够10位 |\n", + "| `123` | `{:>10d}` | `' 123'` | 左边补空格,补够10位 |\n", + "| `123` | `{:<10d}` | `'123 '` | 右边补空格,补够10位 |\n", + "| `123456789` | `{:,}` | `'123,456,789'` | 逗号分隔格式 |\n", + "| `0.123` | `{:.2%}` | `'12.30%'` | 百分比格式 |\n", + "| `123456789` | `{:.2e}` | `'1.23e+08'` | 科学计数法格式 |\n", + "\n", + "^, <, > 分别是居中、左对齐、右对齐,后面带宽度, : 号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。+ 表示在正数前显示 +,负数前显示 -; (空格)表示在正数前加空格\n", + "b、d、o、x 分别是二进制、十进制、八进制、十六进制。\n", + "此外我们可以使用大括号 {} 来转义大括号。\n", + "\n", + "(5)字符串不是特殊的列表,也不是特殊的元组;它是 Python 里独立的一种不可变序列类型(str),专门为文本处理而优化。\n", + "\n", + "(6)字符串用三引号,无需转义特殊字符,同时可以保持字符格式,所见即所得\n", + "\n", + "2.字符串内置的方法\n", + "字符串连接:`+` 、`''.join()`\n", + "| 分类 | 方法 | 描述 | 示例代码 |\n", + "|--------|-------------------------------|--------------------------------------|------------------------------------|\n", + "| 格式化方法 | capitalize() | 将字符串的第一个字符转换为大写。 | `'abc'.capitalize()` |\n", + "| | center(width, fillchar) | 返回一个指定宽度 `width` 居中的字符串,`fillchar` 为填充字符,默认为空格。 | `'abc'.center(10, '-')` |\n", + "| | ljust(width, fillchar) | 返回一个左对齐的字符串,使用 `fillchar` 填充至长度 `width`。 | `'abc'.ljust(10, '-')` |\n", + "| | rjust(width, fillchar) | 返回一个右对齐的字符串,使用 `fillchar` 填充至长度 `width`。 | `'abc'.rjust(10, '-')` |\n", + "| | zfill(width) | 返回长度为 `width` 的字符串,原字符串右对齐,前面填充 `0`。 | `'abc'.zfill(5)` |\n", + "| | title() | 返回标题化的字符串,即每个单词首字母大写,其余字母小写。 | `'hello world'.title()` |\n", + "| 查找方法 | find(str, beg=0, end=len()) | 检测 `str` 是否包含在字符串中,返回索引值,若不存在返回 -1。 | `'abc'.find('b', 0, 3)` |\n", + "| | index(str, beg=0, end=len()) | 类似于 `find()`,但若 `str` 不存在则抛出异常。 | `'abc'.index('b', 0, 3)` |\n", + "| | rfind(str, beg, end) | 类似于 `find()`,但从右边开始查找。 | `'abcabc'.rfind('a', 0, 6)` |\n", + "| | rindex(str, beg, end) | 类似于 `index()`,但从右边开始查找。 | `'abcabc'.rindex('a', 0, 6)` |\n", + "| 检查方法 | isalnum() | 检查字符串是否只由字母和数字组成,若是则返回 `True`,否则返回 `False`。 | `'abc123'.isalnum()` |\n", + "| | isalpha() | 检查字符串是否只由字母组成,若是则返回 `True`,否则返回 `False`。 | `'abc'.isalpha()` |\n", + "| | isdigit() | 检查字符串是否只包含数字,若是则返回 `True`,否则返回 `False`。 | `'123'.isdigit()` |\n", + "| | islower() | 检查字符串是否全为小写字母,若是则返回 `True`,否则返回 `False`。 | `'abc'.islower()` |\n", + "| | isupper() | 检查字符串是否全为大写字母,若是则返回 `True`,否则返回 `False`。 | `'ABC'.isupper()` |\n", + "| | isnumeric() | 检查字符串是否只包含数字字符,若是则返回 `True`,否则返回 `False`。 | `'123'.isnumeric()` |\n", + "| | isspace() | 检查字符串是否只包含空白字符,若是则返回 `True`,否则返回 `False`。 | `' '.isspace()` |\n", + "| | istitle() | 检查字符串是否是标题化的,若是则返回 `True`,否则返回 `False`。 | `'Hello World'.istitle()` |\n", + "| 替换方法 | replace(old, new, max) | 将字符串中的 `old` 替换为 `new`,若指定 `max` 则替换不超过 `max` 次。| `'abcabc'.replace('a', 'x', 1)`|\n", + "| 分割方法 | split(str, num) | 以 `str` 为分隔符截取字符串,若指定 `num`,则仅截取 `num+1` 个子字符串。 | `'a,b,c'.split(',')` |\n", + "| | splitlines(keepends) | 按行分隔字符串,若 `keepends=True`,则保留换行符。 | `'a\\\\nb'.splitlines()` |\n", + "| 去空格方法 | strip(chars) | 截掉字符串两端的空格或指定字符。 | `' abc '.strip()` |\n", + "| | lstrip(chars) | 截掉字符串左边的空格或指定字符。 | `' abc'.lstrip()` |\n", + "| | rstrip(chars) | 截掉字符串右边的空格或指定字符。 | `'abc '.rstrip()` |\n", + "| 连接方法 | join(seq) | 以指定字符串作为分隔符,将 `seq` 中的元素合并为一个新的字符串。 | `','.join(['a', 'b', 'c'])` |\n", + "| 大小写方法 | lower() | 将字符串中的所有大写字符转换为小写。 | `'ABC'.lower()` |\n", + "| | upper() | 将字符串中的所有小写字母转换为大写。 | `'abc'.upper()` |\n", + "| | swapcase() | 将字符串中的大写转换为小写,小写转换为大写。 | `'AbC'.swapcase()` |\n", + "| 映射方法 | maketrans(x, y) | 创建字符映射表,`x` 表示需要转换的字符,`y` 表示转换的目标字符。 | `str.maketrans('a', 'b')` |\n", + "| | translate(table, deletechars) | 根据 `table` 转换字符串的字符,`deletechars` 指定要过滤掉的字符。 | `'abc'.translate({97: 98})` |\n", + "| 其他方法 | len(string) | 返回字符串的长度。 | `len('abc')` |\n", + "| | expandtabs(tabsize=8) | 将字符串中的 tab 符号替换为空格,`tabsize` 指定空格数,默认为 8。 | `'\\tabc'.expandtabs(4)` |\n", + "| | max(str) | 返回字符串中最大的字符。 | `max('abc')` |\n", + "| | min(str) | 返回字符串中最小的字符。 | `min('abc')` |\n", + "3.字符串中的常量\n", + "`string.ascii_letters`:包含所有英文字母(大小写)。\n", + "`string.digits`:包含所有数字字符(0-9)。\n", + "`string.punctuation`:包含所有标点符号。" + ] + }, + { + "cell_type": "markdown", + "id": "4d473164", + "metadata": {}, + "source": [ + "##### 列表([])\n", + "1.列表也可以被索引和截取,截取后返回一个新列表,也可以用+、*运算。\n", + "2.列表中的元素可以改变,字符串中的元素不可以改变。\n", + "3.字符串和元组都属于序列(Sequence)类型,如下图所示:\n", + "Python有6个序列的内置类型,最常见的是列表和元组。\n", + "```python\n", + "object\n", + " └── collections.abc.Iterable\n", + " └── collections.abc.Sequence\n", + " ├── list(可变序列)\n", + " ├── tuple(不可变序列)\n", + " └── str(不可变序列,但元素必须是字符)\n", + "\n", + "```\n", + "4.列表内的元素不需要具有相同的类型。\n", + "5.列表支持嵌套\n", + "5.列表内置的方法\n", + "列表的数据可以修改或更新:\n", + "新增:append()方法可以添加列表项;\n", + "删除:del语句可以删除列表中的指定元素,按照索引制定。\n", + "pop()\n", + "6.列表脚本运算符\n", + "和字符串一样,+ * in \n", + "\n", + "7.列表的函数\n", + "len()列表元素个数\n", + "max(list)、min(list)返回列表元素最大值、最小值\n", + "list(seq)将序列转化为列表\n", + "seq -- 元素列表,可以是列表、元组、集合、字典,若为字典,则仅会将键(key)作为元素依次添加至原列表的末尾。\n", + "\n", + "8.列表的方法\n", + "| 序号 | 语法 | 功能解释 |\n", + "|------|-----------------------------|---------------------------------------------|\n", + "| 1 | `list.append(obj)` | 在列表末尾添加新的对象 |\n", + "| 2 | `list.count(obj)` | 统计某个元素在列表中出现的次数 |\n", + "| 3 | `list.extend(seq)` | 在列表末尾一次性追加另一个序列中的多个值 |\n", + "| 4 | `list.index(obj)` | 从列表中找出某个值第一个匹配项的索引位置 |\n", + "| 5 | `list.insert(index, obj)` | 将对象插入列表,index是要插入对象的索引位置|\n", + "| 6 | `list.pop([index=-1])` | 移除列表中的一个元素(默认最后一个),并返回该元素 |\n", + "| 7 | `list.remove(obj)` | 移除列表中某个值的第一个匹配项 |\n", + "| 8 | `list.reverse()` | 反向列表中元素 |\n", + "| 9 | `list.sort(key=None, reverse=False)` | 对原列表进行排序 |\n", + "| 10 | `list.clear()` | 清空列表,类似于del a[:] |\n", + "| 11 | `list.copy()` | 复制列表,并返回复制后的新列表 |\n", + "\n", + "`list.sort(key=None, reverse=False)`单独解释:\n", + "(1)默认排序规则:默认升序(从小到大)`reverse=False`,`reverse=True`的时候是降序(从大到小)。字母以及特殊字符的降序规则基于字符的 ASCII/Unicode 值。例如升序情况下,a(ASCII值为97)大于A(ASCII值为65),A排在a之前\n", + "(2)key是一个函数,该函数会作用于可迭代对象的每个元素,返回一个值,再以这个值对可迭代对象中的元素进行排序。\n", + "按字符串长度排序:key=len\n", + "按绝对值排序:key=abs\n", + "忽略大小写排序:key=str.lower\n", + "按元组的某个元素排序:key=lambda x: x[1]\n", + "\n", + "9.列表的函数和方法的区别\n", + "| 区别 | 列表的函数 | 列表的方法 |\n", + "|--------|---------------------|--------------------------------|\n", + "| 定义 | 全局函数,作用于列表或其他可迭代对象。通常为Python的内置函数 | 列表对象的成员函数,仅作用于列表。 |\n", + "| 调用方式 | `函数(列表)` | `列表.方法()` |\n", + "| 作用范围 | 可以作用于其他可迭代对象(如元组、集合)。 | 仅适用于列表。 |\n", + "| 示例 | `len(lst)`、`max(lst)` | `lst.append(4)`、`lst.sort()` |\n", + "\n", + "10.嵌套列表\n", + "```python\n", + "matrix = [ # 3X4的矩阵列表\n", + "[1, 2, 3, 4],\n", + "[5, 6, 7, 8],\n", + "[9, 10, 11, 12],\n", + "]\n", + "# 3X4 转为 4X3:\n", + "m2 = [[row(i) for row in matrix] for i in range(4)]\n", + "# 或者\n", + "transposed = []\n", + "for i in range(4):\n", + " transpoed.append([row[i] for row in matrix]) \n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "d37fae74", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]\n", + "[1, 2, 3, 4]\n", + "[5, 6, 7, 8]\n", + "[9, 10, 11, 12]\n", + "[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]\n" + ] + } + ], + "source": [ + "matrix = [\n", + "[1, 2, 3, 4],\n", + "[5, 6, 7, 8],\n", + "[9, 10, 11, 12],\n", + "]\n", + "print(matrix)\n", + "for row in matrix:\n", + " print(row)\n", + "m2 = [[row[i] for row in matrix] for i in range(4)]\n", + "print(m2)" + ] + }, + { + "cell_type": "markdown", + "id": "6663e0af", + "metadata": {}, + "source": [ + "##### 元组(())\n", + "1.元组不能修改(修改删除个别元素),元组内的元素类型可以不同。元组支持切片和索引。\n", + "2.元组可以包含list列表这种可变的对象。\n", + "3.特殊表示\n", + "`tup1 = () # 空元组`\n", + "`tup2 = (20,) # 一个元素,需要在元素后添加逗号,否则就会成为数学运算中的括号`\n", + "4.元组支持 + += * in 迭代\n", + "5.元组的内置函数与list基本相同,除了 tuple(iterable),该函数可将可迭代系列转换为元组" + ] + }, + { + "cell_type": "markdown", + "id": "2597e067", + "metadata": {}, + "source": [ + "##### 字典({})\n", + "1.列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的(所以键必须唯一),而不是通过偏移存取。\n", + "2.字典是一种映射类型,是一个无序的键(唯一key) : 值(value) 的集合。\n", + "```python\n", + "dict1 = {}\n", + "dict1['one'] = \"1 - 菜鸟教程\"\n", + "dict1[2] = \"2 - 菜鸟工具\"\n", + "tinydict = {'name': 'runoob','code':1, 'site': 'www.runoob.com'}\n", + "\n", + "print (dict['one']) # 输出键为 'one' 的值,'1 - 菜鸟教程'\n", + "print (dict[2]) # 输出键为 2 的值,'2 - 菜鸟工具'\n", + "print (tinydict) # 输出完整的字典,'{'name': 'runoob', 'code': 1, 'site': 'www.runoob.com'}'\n", + "print (tinydict.keys()) # 输出所有键,'dict_keys(['name', 'code', 'site'])'\n", + "print (tinydict.values()) # 输出所有值,'dict_values(['runoob', 1, 'www.runoob.com'])'\n", + "```\n", + "3.字典的构造函数dict()\n", + "```python\n", + "dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)]) # 列表形式\n", + "{'Runoob': 1, 'Google': 2, 'Taobao': 3}\n", + ">>> {x: x**2 for x in (2, 4, 6)} # 字典推导式形式\n", + "{2: 4, 4: 16, 6: 36}\n", + ">>> dict(Runoob=1, Google=2, Taobao=3) # a=1形式\n", + "{'Runoob': 1, 'Google': 2, 'Taobao': 3}\n", + "```\n", + "4.字典内置函数?内置方法?\n", + "len(dict1) 返回字典的键值对个数\n", + "str(dict1) 返回字典的字符串表示\n", + "内置方法:\n", + "| 序号 | 语法 | 功能解释 |\n", + "|------|-------------------------------|--------------------------------------------------------------------------|\n", + "| 1 | `dict.clear()` | 删除字典内所有元素,删除后字典对象还在 |\n", + "| 2 | `dict.copy()` | 返回一个字典的浅复制 |\n", + "| 3 | `dict.fromkeys(seq, val)` | 创建一个新字典,以序列 `seq` 中元素做字典的键,`val` 为字典所有键对应的初始值 |\n", + "| 4 | `dict.get(key, default=None)` | 返回指定键的值,如果键不在字典中返回 `default` 设置的默认值 |\n", + "| 5 | `key in dict` | 如果键在字典 `dict` 里返回 `True`,否则返回 `False` |\n", + "| 6 | `dict.items()` | 以列表返回一个视图对象,包含字典的键值对 |\n", + "| 7 | `dict.keys()` | 返回一个视图对象,包含字典的所有键 |\n", + "| 8 | `dict.setdefault(key, default=None)` | 和 `get()` 类似,但如果键不存在于字典中,将会添加键并将值设为 `default` |\n", + "| 9 | `dict.update(dict2)` | 把字典 `dict2` 的键/值对更新到 `dict` 里 |\n", + "| 10 | `dict.values()` | 返回一个视图对象,包含字典的所有值 |\n", + "| 11 | `dict.pop(key[, default])` | 删除字典 `key` 所对应的值,返回被删除的值 |\n", + "| 12 | `dict.popitem()` | 返回并删除字典中的最后一对键和值 |\n", + "\n", + "dict.items()、dict.keys()、dict.values()返回的是一个视图对象,是什么意思?视图就是给个窗口看到当前字典的内容\n", + "好像生成的是一个元组?\n", + "\n", + "5.字典的key是什么类型?\n", + "key必须可哈希(不可变类型,如str、int、tuple)\n", + "6.删除字典元素\n", + "del tinydict['key1'] 删除指定的键值对\n", + "tinydict.clear() 清空字典\n", + "del tinydict 删除字典\n", + "\n", + "7.遍历技巧\n", + "(1)字典的关键字和对应值,可以使用items()方法同时解读出来\n", + "`for k,v in dict1.items()`\n", + "(2)序列中遍历时,索引位置和对应值可以用enumerate()函数同时得到\n", + "`for i,v in enumerate(list1)`,`print(i,v)`i,v分别是索引位置和对应值\n", + "(3)同时遍历多个序列,可以用zip组合\n", + "for q,a in zip(list1,list2)\n", + "(4)反向遍历一个序列,先制定这个序列,然后调用reversed()函数\n", + "`for i in reversed(list)`\n", + "要顺序遍历一个序列,可以用sorted,sorted(list),不会修改原值" + ] + }, + { + "cell_type": "markdown", + "id": "58078555", + "metadata": {}, + "source": [ + "##### 集合({})\n", + "1.集合(Set)是一种无序、可变的数据类型,用于存储唯一的元素。\n", + "2.集合可以进行集合操作(交集、并集、差集)\n", + "3.创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。\n", + "```python\n", + "sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}\n", + "# 也可以用site()创建 sites = srt(('Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'))\n", + "print(sites) # 输出集合,重复的元素被自动去掉\n", + "\n", + "# 成员测试\n", + "if 'Runoob' in sites :\n", + " print('Runoob 在集合中')\n", + "else :\n", + " print('Runoob 不在集合中')\n", + "\n", + "# set可以将其他类型转换为集合\n", + "a = set('abracadabra')\n", + "b = set('alacazam')\n", + "\n", + "print(a) # 重复元素会被去掉,{'b', 'c', 'r', 'a', 'd'}\n", + "print(a - b) # a 和 b 的差集,{'r', 'b', 'd'}\n", + "print(a | b) # a 和 b 的并集,{'b', 'c', 'a', 'z', 'm', 'r', 'l', 'd'}\n", + "print(a & b) # a 和 b 的交集,{'c', 'a'}\n", + "print(a ^ b) # a 和 b 中不同时存在的元素,{'z', 'b', 'm', 'r', 'l', 'd'}\n", + "```\n", + "4.集合的基本操作\n", + "\n", + "| 方法 | 描述 |\n", + "|-------------------------------|----------------------------------------------------------------------|\n", + "| `add()` | 为集合添加元素 |\n", + "| `clear()` | 移除集合中的所有元素 |\n", + "| `copy()` | 拷贝一个集合 |\n", + "| `difference()` | 返回多个集合的差集,例如x.difference(y),返回在x中,不在y中的元素 |\n", + "| `difference_update()` | 移除两个集合中都存在的元素,没有返回值 |\n", + "| `discard()` | 删除集合中指定的元素 |\n", + "| `intersection()` | 返回集合的交集,两个集合都有的元素 |\n", + "| `intersection_update()` | 返回集合的交集,并更新当前集合 |\n", + "| `isdisjoint()` | 判断两个集合是否包含相同的元素,如果没有返回 `True`,否则返回 `False` |\n", + "| `issubset()` | 判断是否为子集,x.issubset(y),x中的所有元素是否都在y中|\n", + "| `issuperset()` | 判断是否为父集,x.issuperset(y),y中的所有元素都在x中 |\n", + "| `pop()` | 随机移除元素 |\n", + "| `remove()` | 移除指定元素 |\n", + "| `symmetric_difference()` | 返回两个集合中不重复的元素集合 |\n", + "| `symmetric_difference_update()` | 移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中 |\n", + "| `union()` | 返回两个集合的并集 |\n", + "| `update()` | 给集合添加元素 |\n", + "| `len()` | 计算集合元素个数 |" + ] + }, + { + "cell_type": "markdown", + "id": "537eaaee", + "metadata": {}, + "source": [ + "#### 推导式\n", + "推导式可以从一个数据序列构建另一个数据序列的结构体,用于生成列表、元组、字典、集合和生成器。\n", + "\n", + "1.列表推导式\n", + "[表达式 for 变量 in 列表 if 条件]\n", + "`[out_exp_res for out_exp in input_list if condition]`\n", + "out_exp_res:列表生成元素表达式,可以是有返回值的函数。\n", + "for out_exp in input_list:迭代 input_list 将 out_exp 传入到 out_exp_res 表达式中。\n", + "if condition:条件语句,可以过滤列表中不符合条件的值。\n", + "\n", + "集合推导式、元组推导式与列表推导式基本相同。\n", + "元组推导式返回的结果是一个生成器对象,要用tuple()函数转换为元组。\n", + "\n", + "也可以判断两个条件,结果2选1:\n", + "结果值1 if 判断条件 else 结果2 for 变量名 in 原列表\n", + "```python\n", + "list1 = ['python', 'test1', 'test2']\n", + "list2 = [word.title() if word.startswith('p') else word.upper() for word in list1]\n", + "print(list2) # 输出['Python', 'TEST1', 'TEST2']\n", + "```\n", + "\n", + "2.字典推导式\n", + "`{key_expr: value_expr for value in collection if condition}`\n", + "key_expr:每次迭代,生成一个字典的键\n", + "value_expr:每次迭代,生成一个字典的值\n", + "collection:可迭代对象\n", + "\n", + "如果字典的键和值分别来自两个可迭代对象,可以使用 zip() 函数(将两个可迭代对象一一配对,生成键值对)结合字典推导式来生成字典:\n", + "`{key: value for key, value in zip(keys_iterable, values_iterable)}`\n", + "备注:两个可迭代对象长度不同,zip()会以较短的可迭代对象为准。" + ] + }, + { + "cell_type": "markdown", + "id": "f72a7ee2", + "metadata": {}, + "source": [ + "#### 迭代器\n", + "1.迭代器是一个可以记住遍历的位置的对象。\n", + "2.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。详细解释:\n", + "(1)迭代器是一个惰性对象,它不会一次性生成所有元素,而是按需生成。\n", + "(2)每次调用 next() 或在 for 循环中迭代时,迭代器会返回下一个元素,并将内部指针移动到下一个位置。\n", + "(3)一旦某个元素被访问过,迭代器的指针就不会再回到之前的位置。\n", + "\n", + "3.迭代器有两个基本的方法:iter() 和 next()。\n", + "\n", + "4.字符串,列表或元组对象都可用于创建迭代器:\n", + "```python\n", + "list1 = [1, 2, 3, 4]\n", + "it = iter(list1) # 创建迭代器对象\n", + "print(type(it)) # 输出: \n", + "\n", + "print(it) # 输出迭代器对象的内存地址\n", + "print(next(it)) # 输出: 1,指针移动到下一个元素\n", + "print(next(it)) # 输出: 2,指针移动到下一个元素\n", + "print(next(it)) # 输出: 3,指针移动到下一个元素\n", + "\n", + "for x in it: # 从当前指针位置开始迭代\n", + " print('迭代:', x) # 输出: 迭代: 4\n", + "```\n", + "\n", + "5.把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。\n", + "\n", + "6.StopIteration用于标识迭代的完成。\n" + ] + }, + { + "cell_type": "markdown", + "id": "0be4e849", + "metadata": {}, + "source": [ + "#### 生成器\n", + "使用了yield的函数称为生成器。\n" + ] + }, + { + "cell_type": "markdown", + "id": "cbf50712", + "metadata": {}, + "source": [ + "#### 函数\n", + "1.python 函数的参数传递:\n", + "不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。\n", + "可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响\n", + "\n", + "2.函数的参数类型:\n", + "必需参数:\n", + "`def printme(str):pass` 必须以正确的顺序,传入相应类型、数量的参数\n", + "关键字参数:\n", + "`def printme(age,name):pass`,可以通过`printme(name='Allen',age=16)`,不按照指定顺序来调用 \n", + "默认参数:\n", + "`def printme(name,age = 35):pass`,35是age参数的默认值,没有传age参数就用默认值\n", + "不定长参数:\n", + "`def printinfo(arg1, *vartuple)`,*vartuple,arg1之外的参数,可以用元组的形式导入,存在所有未命名的变量参数\n", + "参数带一个*是元组,两个**是字典,例如`def printinfo(arg1, **vardict)`调用时,用`printinfo(arg1,a=1,b=2)`\n", + "*的其他作用,单独出现星号时,其后的参数必须用关键字传入,如`def f(a,b,*,c)`里面的c,必须用关键字c=1传入\n", + "Python3.8的强制位置参数,`def f(a, b, /, c, d, *, e, f)`,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参。\n", + "\n", + "3.匿名函数\n", + "匿名的含义:不再使用def标准形式来定义一个函数。匿名的另一个意思是,lambda函数没有函数名称,只能通过赋值给变量或参数。\n", + "用lambda表达式来创建匿名函数,语法为:`lambda [arg1 [,arg2,.....argn]]:expression`,`expression`用于计算并返回函数的结果\n", + "匿名函数可以封装在一个函数内,可以使用同样的代码来创建多个匿名函数。\n", + "lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数?lambda里面的x的范围仅限于lambda语句本身。\n", + "\n", + "lambda函数通常与map()、filter()、reduce()一起使用,便于在集合上操作,例如:\n", + "把列表的元素翻倍:`list(map(lambda x:x*2,list1))`\n", + "筛选列表中的偶数:`list(filter(lambda x:x%2==0,list1))`,filter筛选,返回True的元素才留下\n", + "计算一个序列的累积乘积:`reduce(lambda x,y:x*y,list1)`,reduce合并(先算1、2,然后用1和2的合并结果与3计算,以此类推),先导入functools模块才可以用。\n", + "\n", + "4.return语句\n", + "return表达式用于退出函数,return不带参数值,调用函数会返回None。" + ] + }, + { + "cell_type": "markdown", + "id": "387f8138", + "metadata": {}, + "source": [ + "#### 装饰器\n", + "含义:装饰器用于动态地修改函数或类的行为,一般用于日志记录、性能分析、权限控制、缓存\n", + "基本语法:\n", + "```python\n", + "# 装饰器本质上是一个接收函数作为输入并返回一个新的包装过后的函数的对象。\n", + "def decorator_function(original_function):\n", + " def wrapper(*args, **kwargs):\n", + " \n", + " before_call_code() # 这里是在调用原始函数前添加的新功能\n", + " \n", + " result = original_function(*args, **kwargs)\n", + " \n", + " after_call_code()# 这里是在调用原始函数后添加的新功能\n", + " \n", + " return result\n", + " return wrapper\n", + "\n", + "# 使用装饰器\n", + "@decorator_function\n", + "def target_function(arg1, arg2):\n", + " pass # 原始函数的实现\n", + "\n", + "'''\n", + "等价于 target_function = time_logger(target_function)\n", + "'''\n", + "```\n", + "解释:使用装饰器时,会将目标函数作为参数传递给装饰器函数,装饰器函数除了会原原本本输出原始函数的原有输出,还会在调用原始函数前、后增加一些功能。\n", + "其中的wrapper函数,是实际会被调用的函数,既包含了原始函数的调用,也在后面增加了额外的行为。\n", + "\n", + "内置装饰器:\n", + "@staticmethod: 将方法定义为静态方法,不需要实例化类即可调用。\n", + "(这个方法/函数和这个类有关,所以就放在里面,而且不用实例化具体对象后再用,方便管理)\n", + "Python默认放在类里面的函数,都是给“对象”用的!\n", + "\n", + "@classmethod: 将方法定义为类方法,第一个参数是类本身(通常命名为 cls)。即站爱\n", + "(当我想操作整个类,而不是某个对象时)\n", + "\n", + "@property: 将方法转换为属性,使其可以像属性一样访问。就是不用加括号了。\n", + "\n", + "##### 类装饰器(后续再看)\n", + "可以动态修改类的行为。它接收一个类作为参数,并返回一个新的类或修改后的类。" + ] + }, + { + "cell_type": "markdown", + "id": "052f3e5c", + "metadata": {}, + "source": [ + "#### Python数据结构\n", + "\n", + "1.栈\n", + "(1)栈是一种后进先出(LIFO, Last-In-First-Out)数据结构,意味着最后添加的元素最先被移除。\n", + "(2)可以用列表来实现栈的功能。\n", + "(3)栈操作:\n", + "压入(Push): 将一个元素添加到栈的顶端。list1.append(x)\n", + "弹出(Pop): 移除并返回栈顶元素。list1.pop()\n", + "查看栈顶元素(Peek/Top): 返回栈顶元素而不移除它。list1[-1]\n", + "检查是否为空(IsEmpty): 检查栈是否为空。判断len(list1)==0\n", + "获取栈的大小(Size): 获取栈中元素的数量。len(list1)\n", + "\n", + "2.队列\n", + "队列是一种先进先出(FIFO, First-In-First-Out)的数据结构,意味着最早添加的元素最先被移除。\n", + "使用列表时,如果频繁地在列表的开头插入或删除元素,性能会受到影响,因为这些操作的时间复杂度是 O(n)。为了解决这个问题,Python 提供了 collections.deque,它是双端队列,可以在两端高效地添加和删除元素。\n", + "```python\n", + "from collections import deque\n", + "\n", + "# 创建一个空队列\n", + "queue = deque()\n", + "\n", + "# 向队尾添加元素\n", + "queue.append('a')\n", + "queue.append('b')\n", + "queue.append('c')\n", + "\n", + "print(\"队列状态:\", queue) # 输出: 队列状态: deque(['a', 'b', 'c'])\n", + "\n", + "# 从队首移除元素\n", + "first_element = queue.popleft()\n", + "print(\"移除的元素:\", first_element) # 输出: 移除的元素: a\n", + "print(\"队列状态:\", queue) # 输出: 队列状态: deque(['b', 'c'])\n", + "\n", + "# 查看队首元素(不移除)\n", + "front_element = queue[0]\n", + "print(\"队首元素:\", front_element) # 输出: 队首元素: b\n", + "\n", + "# 检查队列是否为空\n", + "is_empty = len(queue) == 0\n", + "print(\"队列是否为空:\", is_empty) # 输出: 队列是否为空: False\n", + "\n", + "# 获取队列大小\n", + "size = len(queue)\n", + "print(\"队列大小:\", size) # 输出: 队列大小: 2\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "9f7a2be8", + "metadata": {}, + "source": [ + "#### 模块\n", + "1.模块用于长久保存方法及变量。\n", + "2.模块可以用于代码复用、命名空间管理、重新组织代码(使程序结构清晰)\n", + "\n", + "3.`import`用于引入模块:\n", + "一个模块只会被导入一次。\n", + "可以设置模块的别名,`import modname as md`\n", + "import语句执行时,Python的查找路径为sys.path,即为:\n", + "(1)当前目录。\n", + "(2)环境变量 PYTHONPATH 指定的目录。\n", + "(3)Python 标准库目录。\n", + "(4).pth 文件中指定的目录。\n", + "\n", + "4.模块里面除了方法定义,还可以包括可执行代码。\n", + "可执行代码在引入模块的时候(仅第一次模块被导入时)会执行。\n", + "\n", + "5.每个某块都有自己的符号表(即命名空间),即为模块内的函数、变量只属于这个模块,不会影响外面的世界。\n", + "\n", + "6.__name__属性:一个模块被另一个程序第一次引入时,其主程序(指的是顶层代码,即未被函数或类封装的代码)将运行。\n", + "如果不想模块内的主程序在模块被引入时自动执行,可以在模块内的主程序设置条件:`if __name__ == '__main__':主程序代码`\n", + "原理为:每个模块都有一个 __name__ 属性。\n", + "如果模块是被直接运行,__name__ 的值为 __main__。\n", + "如果模块是被导入的,__name__ 的值为模块名。\n", + "\n", + "7.dir()函数\n", + "内置函数,可以找到对应模块所有的名称,以字符串列表形式返回。\n", + "\n", + "8.包\n", + "包可以理解为包含很多某块的文件夹,目的是减少模块间的命名冲突,方便代码管理和后续维护。\n", + "导入包时,Python会根据sys.path中的目录来寻找这个包中包含的子目录。目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包。\n", + "如果包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。\n", + "使用 from Package import specific_submodule 这种方法永远不会有错。" + ] + }, + { + "cell_type": "markdown", + "id": "31e01658", + "metadata": {}, + "source": [ + "#### 标准模块\n", + "| 模块名 | 功能描述 | 常用函数/变量 | 举例说明 | 用法说明 |\n", + "|--------------|-----------------------------------|----------------------------------------|---------------------------------------|---------------------------------------|\n", + "| `math` | 数学运算(如平方根、三角函数等) | `sqrt`, `sin`, `cos`, `pi`, `factorial`| `import math; print(math.sqrt(16))` | `sqrt`: 计算平方根;`sin`, `cos`: 计算正弦、余弦;`pi`: 圆周率;`factorial`: 计算阶乘 |\n", + "| `os` | 操作系统相关功能(如文件、目录操作)| `listdir`, `mkdir`, `remove`, `getcwd` | `import os; print(os.getcwd())` | `listdir`: 列出目录内容;`mkdir`: 创建目录;`remove`: 删除文件;`getcwd`: 获取当前工作目录 |\n", + "| `sys` | 系统相关的参数和函数 | `argv`, `path`, `exit`, `platform` | `import sys; print(sys.platform)` | `argv`: 命令行参数列表;`path`: 模块搜索路径;`exit`: 退出程序;`platform`: 获取操作系统名称 |\n", + "| `random` | 生成随机数 | `randint`, `choice`, `shuffle`, `random`| `import random; print(random.randint(1, 10))` | `randint`: 生成指定范围内的随机整数;`choice`: 随机选择一个元素;`shuffle`: 打乱序列;`random`: 生成0到1之间的随机浮点数 |\n", + "| `datetime` | 处理日期和时间 | `datetime`, `date`, `timedelta`, `now` | `from datetime import datetime; print(datetime.now())` | `datetime`: 日期时间类;`date`: 日期类;`timedelta`: 时间差类;`now`: 获取当前时间 |\n", + "| `json` | 处理 JSON 数据 | `load`, `loads`, `dump`, `dumps` | `import json; print(json.dumps({'a': 1}))` | `load`: 从文件加载JSON;`loads`: 从字符串加载JSON;`dump`: 将JSON写入文件;`dumps`: 将对象转换为JSON字符串 |\n", + "| `re` | 正则表达式操作 | `match`, `search`, `findall`, `sub` | `import re; print(re.findall(r'\\\\d+', 'abc123'))` | `match`: 从字符串开头匹配;`search`: 搜索匹配;`findall`: 查找所有匹配;`sub`: 替换匹配内容 |\n", + "| `collections`| 提供额外的数据结构(如 defaultdict、deque)| `Counter`, `defaultdict`, `deque`, `OrderedDict` | `from collections import Counter; print(Counter('abcabc'))` | `Counter`: 统计元素出现次数;`defaultdict`: 带默认值的字典;`deque`: 双端队列;`OrderedDict`: 有序字典 |\n", + "| `itertools` | 提供迭代器工具 | `count`, `cycle`, `permutations`, `combinations` | `import itertools; print(list(itertools.permutations('abc', 2)))` | `count`: 无限计数器;`cycle`: 无限循环迭代;`permutations`: 排列;`combinations`: 组合 |\n", + "| `functools` | 高阶函数工具(如 reduce、lru_cache)| `reduce`, `lru_cache`, `partial`, `wraps` | `from functools import reduce; print(reduce(lambda x, y: x + y, [1, 2, 3]))` | `reduce`: 累积计算;`lru_cache`: 缓存函数结果;`partial`: 创建偏函数;`wraps`: 保留原函数元信息 |\n" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "2f5af475", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['In',\n", + " 'MyNumbers',\n", + " 'Out',\n", + " 'Person',\n", + " 'User',\n", + " '_',\n", + " '_23',\n", + " '_24',\n", + " '_25',\n", + " '_46',\n", + " '__',\n", + " '___',\n", + " '__builtin__',\n", + " '__builtins__',\n", + " '__doc__',\n", + " '__loader__',\n", + " '__name__',\n", + " '__package__',\n", + " '__spec__',\n", + " '__vsc_ipynb_file__',\n", + " '_dh',\n", + " '_i',\n", + " '_i1',\n", + " '_i10',\n", + " '_i11',\n", + " '_i12',\n", + " '_i13',\n", + " '_i14',\n", + " '_i15',\n", + " '_i16',\n", + " '_i17',\n", + " '_i18',\n", + " '_i19',\n", + " '_i2',\n", + " '_i20',\n", + " '_i21',\n", + " '_i22',\n", + " '_i23',\n", + " '_i24',\n", + " '_i25',\n", + " '_i26',\n", + " '_i27',\n", + " '_i28',\n", + " '_i29',\n", + " '_i3',\n", + " '_i30',\n", + " '_i31',\n", + " '_i32',\n", + " '_i33',\n", + " '_i34',\n", + " '_i35',\n", + " '_i36',\n", + " '_i37',\n", + " '_i38',\n", + " '_i39',\n", + " '_i4',\n", + " '_i40',\n", + " '_i41',\n", + " '_i42',\n", + " '_i43',\n", + " '_i44',\n", + " '_i45',\n", + " '_i46',\n", + " '_i47',\n", + " '_i5',\n", + " '_i6',\n", + " '_i7',\n", + " '_i8',\n", + " '_i9',\n", + " '_ih',\n", + " '_ii',\n", + " '_iii',\n", + " '_oh',\n", + " 'c',\n", + " 'changeme',\n", + " 'count',\n", + " 'dict1',\n", + " 'dicts1',\n", + " 'exit',\n", + " 'get_ipython',\n", + " 'i',\n", + " 'it',\n", + " 'keys',\n", + " 'list1',\n", + " 'm2',\n", + " 'matrix',\n", + " 'my_decorater',\n", + " 'my_func',\n", + " 'myclass',\n", + " 'myiter',\n", + " 'names',\n", + " 'open',\n", + " 'p',\n", + " 'printme',\n", + " 'quit',\n", + " 'row',\n", + " 'set1',\n", + " 'sys',\n", + " 'tup1',\n", + " 'u',\n", + " 'values',\n", + " 'x']" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dir()" + ] + }, + { + "cell_type": "markdown", + "id": "03730363", + "metadata": {}, + "source": [ + "#### with\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "66995658", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n" + ] + } + ], + "source": [ + "def count():\n", + " n = 1\n", + " while n <= 3:\n", + " yield n\n", + " n+=1\n", + "c = count()\n", + "print(next(c))\n", + "print(next(c))\n", + "print(next(c))" + ] + }, + { + "cell_type": "markdown", + "id": "e94367dc", + "metadata": {}, + "source": [ + "#### Python魔法方法\n", + "魔法方法也成双下划线方法。\n", + "本质:魔法方法不是给你“直接调用”的,而是让Python在“特定时机”自动调用的。\n", + "例如,执行`a+b`时,Python自动调用了`a.__add__(b)`\n", + "目的:为了让“自定义对象”表现得像内置类型一样自然,可以直接(+ - * /、用len()、for...in、print()、==等,普通方法无法做到)\n", + "注意事项:\n", + "(1)魔法方法是Python解释器和对象之间的“协议接口”,实现了这个接口,Python才知道什么时候能for、能+、能len、能print\n", + "(2)\n", + "分类(四大类魔法方法):\n", + "1.对象创建与生命周期\n", + "(1)__new__:负责创建对象,返回一个实例\n", + "例如`obj = MyClass()`,Python做的其实是`obj=MyClass.__new__(MyClass)`,参数为cls\n", + "(2)__init__:不创建对象,而是“配置已经创建好的对象”,初始化对象的属性,`MyClass.__init__(obj)`,参数为self\n", + "(3)__del__:在对象被垃圾回收前调用,资源释放一般用with\n", + "2.对象表现(打印/转字符串)\n", + "Python很多地方需要用字符串(print、日志等),所以对象必须能够变成字符串。\n", + "(1)__str__:给“人”看的字符串。\n", + "(2)__repr__:给“程序员/调试”看的字符串。定义对象“真实、准确、不模糊”的表示。\n", + "__str__与__repr__的区别:\n", + "pirnt(obj),优先用__str__;\n", + "如果没有__str__,就用__repr__\n", + "如都没有,输出<__main__.Class object at 0x...>\n", + "3.容器/迭代协议\n", + "容器可以看做是一组行为,一个对象支持这些操作之一就会像个容器:len、for x in obj、obj[i]、x in obj\n", + "__len__\n", + "__iter__\n", + "__next__\n", + "__getitem__\n", + "4.运算符与比较\n", + "__add__\n", + "__eq__\n", + "__lt__\n", + "...\n", + "\n", + "#### 魔法变量" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f0d4d4f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.User at 0x22ba7c7b4a0>" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "class User:\n", + " def __repr__(self):\n", + " return 'User(id=1)'\n", + "u = User()\n", + "u" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7cf54385", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "class MyNumbers:\n", + " def __iter__(self):\n", + " self.a = 1\n", + " return self\n", + "\n", + " def __next__(self):\n", + " x = self.a\n", + " self.a += 1\n", + " return self.a\n", + "\n", + "myclass = MyNumbers()\n", + "myiter = iter(myclass) # iter()是一个内置函数,内置函数的工作规则:如果对象有__iter__方法,就用对象的方法;否则尝试__getitem__(0),__getitem__(1)\n", + "# 所以,这一步等价于 myclass.__iter__,用的是我自己定义的Mynumbers.__iter__\n", + "\n", + "print(next(myiter))\n", + "\n", + "# 我这样做的含义是什么,我重写了__iter__()和__next()方法吗? 那myiter = iter(myclass)这一步用的是哪个iter方法?" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "9c5a47ca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'a': 1, 'b': 2, 'c': 3}\n", + "\n", + "('g', 's', 'i', 'n', 't')\n" + ] + } + ], + "source": [ + "keys = ['a','b','c']\n", + "values = [1,2,3]\n", + "dicts1 = {key:value for key,value in zip(keys,values)}\n", + "tup1 = tuple({x for x in 'sitting'})\n", + "print(dicts1)\n", + "print(type(dicts1))\n", + "print(tup1)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "6f292d99", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2, 4, 6]\n" + ] + } + ], + "source": [ + "names = [x for x in range(1,7) if x%2 == 0 ]\n", + "print(names)" + ] + }, + { + "cell_type": "markdown", + "id": "a1e3ef90", + "metadata": {}, + "source": [ + "#### 条件控制\n", + "1.if语句\n", + "```python\n", + "if condition_1: # condition_1 为True时,执行block_1\n", + " statement_block_1\n", + "elif condition_2: # condition_1 为False时,condition_2 为 False时,执行block_2\n", + " statement_block_2\n", + "else:\n", + " statement_block_3 # 否则执行block_3\n", + "```\n", + "\n", + "2.match...case条件判断(Python3.10版后引入的)\n", + "支持匹配值(多个值用|)、匹配类型、匹配结构(list、dict、class)、匹配并绑定变量、支持守卫条件(case if ...)\n", + "(1)基础语法\n", + "```python\n", + "match expression:\n", + " case pattern1:\n", + " # 处理pattern1的逻辑\n", + " case pattern2 if condition:\n", + " # 处理pattern2并且满足condition的逻辑\n", + " case _:\n", + " # 处理其他情况的逻辑\n", + "```\n", + "(2)可以匹配并绑定变量\n", + "```python\n", + "def match_example(item):\n", + " match item:\n", + " case (x, y) if x == y:\n", + " print(f\"匹配到相等的元组: {item}\")\n", + " case (x, y):\n", + " print(f\"匹配到元组: {item}\")\n", + " case _:\n", + " print(\"匹配到其他情况\")\n", + "\n", + "match_example((1, 1)) # 输出: 匹配到相等的元组: (1, 1)\n", + "match_example((1, 2)) # 输出: 匹配到元组: (1, 2)\n", + "match_example(\"other\") # 输出: 匹配到其他情况\n", + "```\n", + "\n", + "```python\n", + "# 复杂的接口返回,想取得关联关系(relation)是什么\n", + "resp = {\n", + " 'code':200,\n", + " 'data':{\n", + " 'company':{\n", + " 'id':'A123',\n", + " 'relationship':'控股'\n", + " }\n", + " }\n", + "}\n", + "# 传统写法\n", + "if resp.get('code') == 200:\n", + " if 'company' in resp['data']:\n", + " relation = resp['data']['company']['relationship']\n", + "# match:\n", + "match resp:\n", + " case {'code':200,'data':{'company':{'id':'A123','relationship':rel}}}: # 匹配并绑定变量\n", + " print('关联关系',rel)\n", + "```\n", + "\n", + "(3)可以匹配类型:\n", + "```python\n", + "class Circle:\n", + " def __init__(self, radius):\n", + " self.radius = radius\n", + "\n", + "class Rectangle:\n", + " def __init__(self, width, height):\n", + " self.width = width\n", + " self.height = height\n", + "\n", + "def match_shape(shape):\n", + " match shape:\n", + " case Circle(radius=1):\n", + " print(\"匹配到半径为1的圆\")\n", + " case Rectangle(width=1, height=2):\n", + " print(\"匹配到宽度为1,高度为2的矩形\")\n", + " case _:\n", + " print(\"匹配到其他形状\")\n", + "\n", + "match_shape(Circle(radius=1)) # 输出: 匹配到半径为1的圆\n", + "match_shape(Rectangle(width=1, height=2)) # 输出: 匹配到宽度为1,高度为2的矩形\n", + "match_shape(\"other\") # 输出: 匹配到其他形状\n", + "```\n", + "\n", + "(4)匹配对象类型:检查对象是不是某种类型,类似于isinstance;\n", + "匹配类对象:不仅检查类型,还要检查对象内部属性结构,并允许提取(绑定)内部的值\n" + ] + }, + { + "cell_type": "markdown", + "id": "f646ca2a", + "metadata": {}, + "source": [ + "#### 循环语句\n", + "1.for循环,用于遍历任何可迭代对象\n", + "\n", + "2.while循环,Python中没有do while循环\n", + "简单循环:while True:print('a')\n", + "\n", + "3.break,跳出当前循环\n", + "\n", + "4.continue,跳出当前循环块中的剩余语句,进行下一次循环" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1924434", + "metadata": {}, + "outputs": [], + "source": [ + "n = 5\n", + "while n > 0:\n", + " n -= 1\n", + " if n == 2:\n", + " continue\n", + " print(n)\n", + "print('end!')" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "8a6179b9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "关联关系 控股\n", + "控股\n" + ] + } + ], + "source": [ + "resp = {\n", + " 'code':200,\n", + " 'data':{\n", + " 'company':{\n", + " 'id':'A123',\n", + " 'relationship':'控股'\n", + " }\n", + " }\n", + "}\n", + "# 传统写法\n", + "if resp.get('code') == 200:\n", + " if 'company' in resp['data']:\n", + " relation = resp['data']['company']['relationship']\n", + "# match:\n", + "match resp:\n", + " case {'code':200,'data':{'company':{'id':'A123','relationship':rel}}}:\n", + " print('关联关系',rel)\n", + " \n", + "\n", + "print(relation)" + ] + }, + { + "cell_type": "markdown", + "id": "429b4e33", + "metadata": {}, + "source": [ + "#### Python 直接赋值、浅拷贝和深度拷贝解析:\n", + "(1)直接赋值:其实就是对象的引用(别名)。\n", + "b=a,即a和b都指向同一个对象。\n", + "(2)浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。\n", + "b=a.copy(),a和b指向不同的对象,但是他们的子对象指向的还是一个对象(是引用)。\n", + "(3)深拷贝(deepcopy):copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。\n", + "b = copy.deepcopy(a),a和b是独立的对象,其中的子对象也是不同的对象。\n", + "```python\n", + "# 字典浅拷贝\n", + "a = {1:[1,2,3]}\n", + "b = a.copy() \n", + "print(a,b) # 输出 {1: [1, 2, 3]} {1: [1, 2, 3]}\n", + "a[1].append(4) # a的子对象和b的子对象是同一个\n", + "print(a,b) # 输出 {1: [1, 2, 3, 4]} {1: [1, 2, 3, 4]}\n", + "\n", + "# 深拷贝\n", + "import copy\n", + "c = copy.deepcopy(a)\n", + "print(a,c) # 输出 {1: [1, 2, 3, 4]} {1: [1, 2, 3, 4]}\n", + "a[1].append(5)\n", + "print(a,c) # 输出 {1: [1, 2, 3, 4, 5]} {1: [1, 2, 3, 4]}\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e71df9a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1: [1, 2, 3]} {1: [1, 2, 3]}\n", + "{1: [1, 2, 3, 4]} {1: [1, 2, 3, 4]}\n", + "{1: [1, 2, 3, 4]} {1: [1, 2, 3, 4]}\n", + "{1: [1, 2, 3, 4, 5]} {1: [1, 2, 3, 4]}\n" + ] + } + ], + "source": [ + "a = {1:[1,2,3]}\n", + "b = a.copy() \n", + "print(a,b) # 输出 {1: [1, 2, 3]} {1: [1, 2, 3]}\n", + "a[1].append(4) # a的子对象和b的子对象是同一个\n", + "print(a,b) # 输出 {1: [1, 2, 3, 4]} {1: [1, 2, 3, 4]}\n", + "# 深拷贝\n", + "import copy\n", + "c = copy.deepcopy(a)\n", + "print(a,c) # 输出 {1: [1, 2, 3, 4]} {1: [1, 2, 3, 4]}\n", + "a[1].append(5)\n", + "print(a,c) # 输出 {1: [1, 2, 3, 4, 5]} {1: [1, 2, 3, 4]}" + ] + }, + { + "cell_type": "markdown", + "id": "7480e222", + "metadata": {}, + "source": [ + "##### bytes类型\n", + "bytes类型表示不可变的二进制序列,其中的元素是整数值(0-255之间的整数)。\n", + "常用于处理二进制数据(图像、音频、视频),网络编程中也用来传输二进制数据。\n", + "bytes与字符串类型一样,也支持切片、拼接、查找、替换等。\n", + "可以使用`b`前缀,或者`bytes()`函数来创建bytes类型对象。\n", + "\n", + "```python\n", + "x = b\"hello\"\n", + "y = bytes('world',encoding='utf-8')\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "60672bf2", + "metadata": {}, + "source": [ + "\n", + "\n", + "##### bool(布尔类型)\n", + "bool是int的子类,`True==1,False==0,issubclass(bool,int)`都返回True。 \n", + "布尔值可以被看作整数来使用,True等价于1,False等价于0。\n", + "`bool()`函数可以将其他类型的值转为布尔值,下面的值会被转为False:\n", + "None、False、零 (0、0.0、0j)、空序列(如 ''、()、[])和空映射(如 {})。其余均为True。 \n", + "常用示例:\n", + "```python\n", + "print(True and False) # False\n", + "print(True or False) # True\n", + "print(not True) # False\n", + "print(not False) # True\n", + "\n", + "x = 10\n", + "if x:\n", + " print(\"x is non-zero and thus True in a boolean context\")\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "9cf899d0", + "metadata": {}, + "source": [ + "#### 数据类型转换\n", + "##### 隐式类型转换\n", + "一般是较低数据类型(如整数)转换为较高数据类型(如浮点数),以避免数据丢失。\n", + "较低:一般指的是表示范围小,表示精度低,内存占用较小,存储结构简单;较高反之。\n", + "特殊://的结果不一定是整数,例如`7.0//2`返回`3.0`。\n", + "##### 显式类型转换\n", + "将对象的数据类型做强制转换。\n", + "```python\n", + "# int():将一个字符串或者数字转换为整型\n", + "print(int('25',base = 10)) # base为进制,默认十进制,明确进制时只能转换字符串\n", + "print(int(2)) # 输出2\n", + "print(int(0b10010) )#输出18,默认输出10进制\n", + "\n", + "# float():将一个数或者字符串转换为浮点数\n", + "print(float(25)) # 输出25.0\n", + "print(float('280')) # 输出280.0\n", + "\n", + "# str():将对象转为字符串,即返回一个对象的string格式\n", + "dict3 = {'runoob': 'runoob.com', 'google': 'google.com'}\n", + "print(dict3) # 输出{'runoob': 'runoob.com', 'google': 'google.com'}\n", + "\n", + "# complex():创建一个复数\n", + "print(complex(1,2)) # 输出(1+2j)\n", + "print(complex(1)) # 输出(1+0j)\n", + "print(complex('1')) # 输出(1+0j),1当做实部处理\n", + "print(complex('1+2j')) # 输出(1+2j)\n", + "\n", + "\n", + "\n", + "# repr():将对象转换为供解释器读取的形式?\n", + "# 将读取到的格式字符,比如换行符、制表符,转化为其相应的转义字符\n", + "s=\"物品\\t单价\\t数量\\n包子\\t1\\t2\"\n", + "print(str(s))\n", + "print(repr(s)) # 转义字符变为正常的字符\n", + "\n", + "# eval():用于执行一个字符串表达式,并返回表达式的值(有风险)\n", + "print(eval('1+2+3')) # 输出6\n", + "\n", + "# tuple(s)、list(s):将可迭代系列s(列表)转换为元组、列表\n", + "list1 = ['Google', 'Taobao', 'Runoob', 2]\n", + "tuple1 = tuple(list1)\n", + "print(tuple1) # 输出('Google', 'Taobao', 'Runoob', 2)\n", + "\n", + "# set():将一个可迭代对象对象转换为集合,可以用于去重、关系测试\n", + "x = set('runoob')\n", + "print(x) # 输出{'n', 'u', 'b', 'r', 'o'}\n", + "\n", + "# frozenset():返回一个冻结的集合,该集合不能添加或删除任何元素。\n", + "a = frozenset(range(10))\n", + "print(a) # 输出 frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})\n", + "b = frozenset('runoob')\n", + "print(b) # 输出 frozenset({'r', 'o', 'n', 'b', 'u'})\n", + "\n", + "# chr(x):将一个整数转换为一个ASCII字符,x可以是十进制也可以是十六进制。\n", + "print(chr(10)) # 输出的是换行符(\\n),相当于print('\\n')\n", + "print(repr(chr(10))) # 输出'\\n'\n", + "\n", + "# ord():将一个字符转换为它的整数值。\n", + "# ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数。\n", + "print(ord('a')) # 输出97\n", + "print(ord('A')) # 输出65\n", + "print(ord('\\n')) # 输出10\n", + "\n", + "# hex():将一个十进制整数转换为十六进制字符串。\n", + "print(hex(255)) # 输出0xff\n", + "\n", + "# oct():将一个整数转换为八进制字符串。\n", + "print(oct(10)) # 输出0o12\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3cf274fb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0o12\n" + ] + } + ], + "source": [ + "print(oct(10))" + ] + }, + { + "cell_type": "markdown", + "id": "9e9d4622", + "metadata": {}, + "source": [ + "dict()构造字典的本质是:能够传入键值对(key,value),就能生成字典。\n", + "传入键值对的方式是:\n", + "1.直接传入关键字:\n", + "```python\n", + "dict3 = dict(a='a',b='b',t='t') # 直接传入关键字构造\n", + "# 等价于 dict3 = (a='a',b='b',t='t')\n", + "print(dict3) # 输出{'a': 'a', 'b': 'b', 't': 't'}\n", + "```\n", + "\n", + "2.用可迭代对象,可迭代对象里面是(key,value)的二元序列即可\n", + "```python\n", + "dict4 = dict([('one',1),('two',2),('three',3)])\n", + "print(dict4) # {'one': 1, 'two': 2, 'three': 3}\n", + "```\n", + "可迭代对象是其他形式(元组、列表、生成器)也可以。\n", + "```python\n", + "dict4 = dict((['a',1],['b',2]))\n", + "dict4 = dict(((1,'x'x),(2,'y')))\n", + "dict4 = dict((f'key{i}',i) for i in range(3))\n", + "```\n", + "原因:dict()会遍历这个列表,每个元素都可以拆分成一个键和一个值。\n", + "\n", + "3.用zip,zip(key,values)会生成一堆(key,value)原则,符合dict需要的格式\n", + "\n", + "4.用映射类型(Mapping)构造。\n", + "映射类型指的是:能通过“键→值”的方式存储和访问数据的容器。\n", + "字典是最典型的映射类型,其他映射类型包括collections.OrderedDict(有序字典)等\n", + "所有映射类型都要能够实现__getitem__、__iter__、__len__\n", + "dict()函数可以接受任何Mapping类型,例如:\n", + "```python\n", + "mapping1 = {'a':1,'b':2}\n", + "d = dict(mapping1)\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "890c875d", + "metadata": {}, + "source": [ + "### 数据类型" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2c895b89", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'a': 1, 'b': 2}\n", + "\n", + "True\n" + ] + } + ], + "source": [ + "from collections.abc import Mapping\n", + "mapping1 = {'a':1,'b':2}\n", + "d = dict(mapping1)\n", + "print(d)\n", + "print(type(mapping1))\n", + "print(isinstance(mapping1,Mapping))" + ] + }, + { + "cell_type": "markdown", + "id": "4b514b92", + "metadata": {}, + "source": [ + "### 函数\n", + "静态方法\n", + "### 模块\n", + "Python中的模块是独立的命名空间,模块中的函数和变量不会自动导入到全局命名空间。\n", + "模块,例如random模块,本身可以看做一个静态对象,可以通过random.choice()来调用random模块中的choice()函数,这种调用方式可以避免命名冲突。\n", + "\n", + "1.静态对象\n", + "(1)含义:静态对象是指在程序运行期间,其状态或行为不会发生改变,或者不需要实例化就可以直接使用的对象。\n", + "(2)常见类型:模块、类的静态成员、不可变对象\n", + "(3)应用场景:静态对象无需实例化即可使用,而动态对象是需要实例化之后才可以使用的对象。而且静态对象创建后不可变。\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2afc559", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25\n", + "2\n", + "18\n", + "25.0\n", + "280.0\n", + "(1+2j)\n", + "(1+0j)\n", + "(1+0j)\n", + "(1+2j)\n", + "{'runoob': 'runoob.com', 'google': 'google.com'}\n", + "物品\t单价\t数量\n", + "包子\t1\t2\n", + "'物品\\t单价\\t数量\\n包子\\t1\\t2'\n", + "6\n", + "('Google', 'Taobao', 'Runoob', 2)\n", + "{'n', 'u', 'b', 'r', 'o'}\n", + "{'a': 'a', 'b': 'b', 't': 't'}\n", + "{'one': 1, 'two': 2, 'three': 3}\n", + "{'one': 1, 'two': 2, 'three': 3}\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "e37f0a41", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "b'He'\n", + "b'Hello'\n" + ] + } + ], + "source": [ + "x = b'Hello'\n", + "print(type(x))\n", + "print(x[0:2])\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "id": "32f5df29", + "metadata": {}, + "source": [ + "### 其他知识点\n", + "1.在 Jupyter Notebook 中执行过的变量会一直保留在当前 Kernel 的内存里 \n", + "可以运行`%whos`(显示变量名、类型、值)、`%who`(只显示变量名)、`dir()`(会把魔法变量也列出来)。 \n", + "可以用`del`语句,删除不想要的变量;或者重启Jupyter Kernel(最彻底)。 \n", + "原因:因为 Jupyter Notebook 的执行模式是 stateful(有状态): \n", + "前面 cell 定义的变量,后面 cell 可以继续用,就算你删除 cell,变量仍然保留,只有重启 Kernel 才会清掉所有变量。" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "b1d24a5a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Variable Type Data/Info\n", + "-----------------------------\n", + "dict2 dict n=0\n", + "dict3 dict n=2\n", + "list1 list n=4\n", + "s str 物品\t单价\t数量\\n包子\t1\t2\n", + "tuple1 tuple n=4\n", + "x set {'n', 'u', 'b', 'r', 'o'}\n" + ] + } + ], + "source": [ + "%whos" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0bd8ee68", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Runoo\n", + "R\n", + "noo\n", + "noob\n", + "Ru\n", + "boonuR\n", + "boonuR\n" + ] + } + ], + "source": [ + "str = 'Runoob'\n", + "print(str[0:-1]) # 'Runoob'\n", + "print(str[0]) # 'R'\n", + "print(str[2:5]) # 'noo'\n", + "print(str[2:]) # 'noob'\n", + "print(str[:2]) # 'Ru'\n", + "print(str[::-1]) # 'boonuR',默认步长为1,步长为-1时会反转\n", + "print(str[-1::-1]) # 'boonuR',默认步长为1,步长为-1时会反转" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ecd9167", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'Runoob': 1, 'Google': 2, 'Taobao': 3}\n", + "{2: 4, 4: 16, 6: 36}\n", + "{'Runoob': 1, 'Google': 2, 'Taobao': 3}\n" + ] + } + ], + "source": [ + "del dict\n", + "\n", + "dict1 = dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)])\n", + "print(dict1) # {'Runoob': 1, 'Google': 2, 'Taobao': 3}\n", + "dict2 = {x: x**2 for x in (2, 4, 6)}\n", + "print(dict2)# {2: 4, 4: 16, 6: 36}\n", + "dict3 = dict(Runoob=1, Google=2, Taobao=3)\n", + "print(dict3) # {'Runoob': 1, 'Google': 2, 'Taobao': 3}" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "040e17dd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'Zhihu', 'Facebook', 'Runoob', 'Taobao', 'Baidu', 'Google'}\n", + "Runoob 在集合中\n", + "{'b', 'c', 'r', 'a', 'd'}\n", + "{'b', 'd', 'r'}\n", + "{'m', 'b', 'c', 'r', 'a', 'd', 'z', 'l'}\n", + "{'a', 'c'}\n", + "{'m', 'b', 'z', 'l', 'r', 'd'}\n" + ] + } + ], + "source": [ + "sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}\n", + "print(sites) # 输出集合,重复的元素被自动去掉\n", + "\n", + "# 成员测试\n", + "if 'Runoob' in sites :\n", + " print('Runoob 在集合中')\n", + "else :\n", + " print('Runoob 不在集合中')\n", + "\n", + "# set可以进行集合运算\n", + "a = set('abracadabra')\n", + "b = set('alacazam')\n", + "\n", + "print(a)\n", + "print(a - b) # a 和 b 的差集\n", + "print(a | b) # a 和 b 的并集\n", + "print(a & b) # a 和 b 的交集\n", + "print(a ^ b) # a 和 b 中不同时存在的元素" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc91bb2b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n", + "True\n", + "True\n", + "True\n" + ] + } + ], + "source": [ + "class A:pass\n", + "class B(A):pass\n", + "\n", + "b = B()\n", + "print(type(b) is B) # True\n", + "print(type(b) is A) # False\n", + "print(isinstance(b,B)) # True\n", + "print(isinstance(b,A)) # True\n", + "print(issubclass(B,A)) # True" + ] + }, + { + "cell_type": "markdown", + "id": "73c336d4", + "metadata": {}, + "source": [ + "### Python错误和警告\n", + "1.`print(1 is True)`会有警告:\n", + "SyntaxWarning:\"is\" with 'int' literal. Did you mean \"==\"?\n", + "2.TypeError: 'dict' object is not callable\n", + "是因为先前的代码把dict类型覆盖成了一个字典对象,导致dict变为一个普通的对象,故报错不可调用。" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "0ae936f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "人会说话\n", + "Allen is learnning 英语\n", + "\n", + "\n", + "False\n", + "True\n", + "True\n", + "False\n", + "False\n" + ] + } + ], + "source": [ + "class Person:\n", + "\n", + " def __init__(self,name,age):\n", + " self.name = name\n", + " self.age = age\n", + " \n", + " def speak(self):\n", + " print(\"人会说话\")\n", + "\n", + "class Student(Person):\n", + "\n", + " def __init__(self,name,age):\n", + " super().__init__(name,age)\n", + " \n", + " def learn(self,course):\n", + " print(f'{self.name} is learnning {course}')\n", + "\n", + "stu1 = Student('Allen',26)\n", + "stu1.speak()\n", + "stu1.learn('英语')\n", + "\n", + "print(type(stu1))\n", + "print(type(Student))\n", + "print(type(stu1) is Person)\n", + "print(isinstance(stu1,Person))\n", + "print(isinstance(stu1,Student))\n", + "print(isinstance(Student,Person))\n", + "print(isinstance(bool,int))" + ] + }, + { + "cell_type": "markdown", + "id": "bc2e5920", + "metadata": {}, + "source": [ + "- 运算符(优先级从高到低)\n", + " - 比较运算符:> >= < <= == !=\n", + " - 赋值运算符:= += *=\n", + " - 逻辑预算符:and or not\n", + " - 数学运算符: + - * / % // **" + ] + }, + { + "cell_type": "markdown", + "id": "1779142d", + "metadata": {}, + "source": [ + "> 字符串属于数据还是数据结构 \n", + "> 数字属于数据还是数据结构 \n", + "> 数据和数据结构有什么关系" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1181ca0f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello\n" + ] + } + ], + "source": [ + "a =10\n", + "a = 'hello'\n", + "print(a)" + ] + }, + { + "cell_type": "markdown", + "id": "b30f7a39", + "metadata": {}, + "source": [ + "### 变量\n", + "- 变量含义\n", + " Python中的变量代表内存中的一个位置?\n", + "- 变量命名规则 \n", + " - Python变量允许以数字+字符(理解为英文字母)+符号,如涉及多个单词之间建议用下划线 \n", + " - 常量为大写\n", + "- 变量类型(需要整合为表格)\n", + " - 可变类型\n", + " - 整数(int)\n", + " - 浮点数(float)\n", + " - 列表(list)\n", + " - \n", + " - 不可变类型\n", + " - 字符串(str)\n", + " - 元组(tuple)\n", + " - 字典(dict)\n", + " - 变量类型的转换\n", + " - 类型转换函数(应该是区分了强制转换和自动转换?)\n", + " - 转换为整数 `int(x)`,转换时可带进制\n", + " - 转换为浮点数`float(x)`\n", + " - 转换为字符串`str(x)`\n", + " - 转换为列表`list(x)`\n", + " - 转换为元组`tuple(x)`\n", + " - 转换为字典?\n", + " - 自动转换\n", + " - 带有浮点数的数学运算的结果,均为float类型 2/1 = 2.0\n", + " - \n", + "- 变量的声明\n", + " - 元组的声明,`tup1 = (1,)`,必须带括号,否则仅为仅为用于确定运算顺序的括号\n", + " - 字典的声明,\n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "ec409422", + "metadata": {}, + "source": [ + "### 基本数据类型\n", + "数据类型对应的方法\n", + "string.split()?" + ] + }, + { + "cell_type": "markdown", + "id": "bcbe2001", + "metadata": {}, + "source": [ + "### 分支循环结构\n", + "- 分支结构 \n", + " if elif else" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c7644079", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "成绩优秀\n" + ] + } + ], + "source": [ + "a = 100\n", + "if a>90:\n", + " print('成绩优秀')\n", + "elif a>60:\n", + " print('成绩合格')\n", + "else:\n", + " print('成绩不合格')" + ] + }, + { + "cell_type": "markdown", + "id": "202e48e0", + "metadata": {}, + "source": [ + "- 循环结构 \n", + " while循环\n", + " for循环\n", + " range函数的问题" + ] + }, + { + "cell_type": "markdown", + "id": "a573f908", + "metadata": {}, + "source": [ + "### 函数\n", + "- 函数的定义\n", + " Python内的函数为\n", + "- 内置函数\n", + "- 装饰器\n", + "- 递归调用" + ] + }, + { + "cell_type": "markdown", + "id": "ff4a1328", + "metadata": {}, + "source": [ + "### 模块\n", + "- 标准库?" + ] + }, + { + "cell_type": "markdown", + "id": "6392017b", + "metadata": {}, + "source": [ + "### 面向对象\n", + "#### 面向对象的含义 \n", + "面向对象编程是一种编程范式(即程序设计的方法论)。\n", + "在面向对象编程的世界里,程序中的**数据和操作数据的函数是一个逻辑上的整体**,称之为**对象**。 \n", + "> 还有指令式变成、函数式编程等编程范式。\n", + "\n", + "对象可以接受消息,解决问题的方法就是创建对象并向对象发出各种各样的消息;通过消息传递,程序中的多个对象可以协同工作,这样就能构造出复杂的系统并解决现实中的问题。\n", + "> 面向对象编程:把一组数据和处理数据的方法组成**对象**,把行为相同的对象归纳为**类**,通过**封装**隐藏对象的内部细节,通过**继承**实现类的特化和泛化,通过**多态**实现基于对象类型的动态分派。\n", + "> - 封装:隐藏内部实现细节,往外暴露简单调用接口。例如在类中定义对象的方法就是封装,给对象发一个消息(即不用明确具体实现)就可以执行方法中的代码。\n", + "#### 面向对象编程三步走\n", + "第一步:定义类 \n", + "定义类就是要找到对象的公共属性或者方法 \n", + "第二步:创建对象 \n", + "第三步:给对象发消息 \n", + "Python内置的list、set、dict都是提前定义好的类,可以跳过第一步; \n", + "如果第一步、第二部都提前走了,就是某些内置对象,可以“开箱即用”。" + ] + }, + { + "cell_type": "markdown", + "id": "cd6c2b68", + "metadata": {}, + "source": [ + "#### 类和对象\n", + "含义:类是对象的蓝图和模板(例如人类),对象是类的实例(例如具体的人),是可以接受消息的实体。 \n", + "> 一切皆为对象,对象都有属性和行为,每个对象都是独一无二的,而且对象一定属于某个类。 \n", + "> 接收消息是什么意思?\n", + "\n", + "属性:属性是对象的静态特征,行为(方法)是对象的动态特征。具有共同特征的对象和属性和行为抽取出来就可以定义一个类。" + ] + }, + { + "cell_type": "markdown", + "id": "cb0d8728", + "metadata": {}, + "source": [ + "类的定义和使用:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04fdc6f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<__main__.Student object at 0x0000024596C1A2D0>\n", + "<__main__.Student object at 0x00000245968E7D40>\n", + "0x24596c1a2d0 0x245968e7d40\n", + "王克章正在学习Python程序设计.\n", + "王大锤学生正在玩游戏.\n", + "王克章正在学习Python程序设计.\n", + "王大锤学生正在玩游戏.\n" + ] + } + ], + "source": [ + "### 类的创建 ###\n", + "class Student:\n", + "\n", + " def __init__(self,name,age): # 初始化方法,即常见对象时,\n", + " #首先会在内存中获取对象的所需的内存空间,然后会自动执行该方法,完成对内存的初始化操作\n", + " self.name = name # 对象属性赋初始化值\n", + " self.age = age # = 右侧的age是传入的参数\n", + "\n", + " def study(self,course_name):\n", + " print(f'{self.name}正在学习{course_name}.')\n", + "\n", + " def play(self):\n", + " print(f'{self.name}学生正在玩游戏.')\n", + "\n", + "### 类的使用 ### \n", + "stu1 = Student('王克章',28) # 构造器语法创建类的对象,此时会传入类的初始化参数\n", + "stu2 = Student('王大锤',25)\n", + "print(stu1) \n", + "# 输出 <__main__.Student object at 0x000002459692B2C0>\n", + "# 上面这个输出代表是一个Student类的对象,以及这个对象的以十六进制表示的内存地址\n", + "# __main__表示Student类定义在主模块中(当前脚本)\n", + "print(stu2) \n", + "# 输出 <__main__.Student object at 0x000002459692B2C0>\n", + "print(hex(id(stu1)),hex(id(stu2)))\n", + "# 函数hex()将整数转为十六进制字符串\n", + "# 函数id()返回对象在内存中的唯一标识(一般是内存地址),该标识在对象的全生命周期内保持一致\n", + "stu3 = stu2 # 并没有创建新的对象\n", + "# 变量存的是一个对象在内存中的逻辑地址(位置)\n", + "\n", + "### 调用对象的方法 ###\n", + "Student.study(stu1,'Python程序设计')# 类.方法(接收消息的对象,方法入参) 来调用\n", + "Student.play(stu2)\n", + "stu1.study('Python程序设计')# 对象.方法(仅为方法入参)来调用\n", + "stu2.play()" + ] + }, + { + "cell_type": "markdown", + "id": "52825732", + "metadata": {}, + "source": [ + "> 写在类里面的函数我们通常称之为方法,方法就是对象的行为,也就是对象可以接收的消息。方法的第一个参数通常都是self,它代表了接收这个消息的对象本身。 \n", + "> 这个self怎么理解?\n", + "> 是不是类中定义的所有函数的第一个参数都要是self?" + ] + }, + { + "cell_type": "markdown", + "id": "aa224ddb", + "metadata": {}, + "source": [ + "#### 面向对象案例" + ] + }, + { + "cell_type": "markdown", + "id": "b339fc8b", + "metadata": {}, + "source": [ + "##### 例子1:时钟\n", + "> 要求:定义一个类描述数字时钟,提供走字和显示时间的功能。" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "4922cdf1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12:26:34\n", + "12:26:35\n", + "12:26:36\n", + "12:26:37\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[5], line 25\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m 24\u001b[0m \u001b[38;5;28mprint\u001b[39m(clock1\u001b[38;5;241m.\u001b[39mshow())\n\u001b[1;32m---> 25\u001b[0m time\u001b[38;5;241m.\u001b[39msleep(\u001b[38;5;241m1\u001b[39m)\n\u001b[0;32m 26\u001b[0m clock1\u001b[38;5;241m.\u001b[39mrun()\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "import time\n", + "\n", + "class Clock: # 定义时钟类\n", + " def __init__(self,hour=0,minute=0,second=0):\n", + " self.hour = hour\n", + " self.min = minute\n", + " self.sec = second\n", + " \n", + " def run(self): # 走字\n", + " self.sec += 1\n", + " if self.sec == 60:\n", + " self.sec = 0\n", + " self.min += 1\n", + " if self.min == 60:\n", + " self.min = 0\n", + " self.hour += 1\n", + " if self.hour == 24:\n", + " self.hour = 0\n", + " def show(self):\n", + " return f'{self.hour:>2d}:{self.min:0>2d}:{self.sec:>02d}'\n", + "\n", + "clock1 = Clock(12,26) # 创建时钟对象\n", + "while True:\n", + " print(clock1.show())\n", + " time.sleep(1)\n", + " clock1.run() " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "caf96148", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72978564", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "c22975b2", + "metadata": {}, + "source": [ + "##### 例2:平面上的点\n", + "> 要求:定义一个类描述平面上的点,提供计算到另一个点距离的方法。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dca8b607", + "metadata": {}, + "outputs": [], + "source": [ + "class Point:\n", + " \"\"\"平面上的点\"\"\"\n", + "\n", + " def __init__(self,x=0,y=0):\n", + " self.x,self.y = x,y\n", + " \n", + " def distance_to(self,other):# other表示另一个对象\n", + " dx = self.x - other.x\n", + " dy = self.y - other.y\n", + " return (dx*dx + dy*dy)**0.5\n", + " \n", + " def __str__(self): # 这个是什么意思?\n", + " # 可以理解为对象的字符串表示形式,就是调整print(对象)显示的内容\n", + " return f'({self.x},{self.y})'\n", + "\n", + "p1 = Point(3,5)\n", + "p2 = Point(6,9)\n", + "print(p1)\n", + "print(p2)\n", + "print(p1.distance_to(p2))\n" + ] + }, + { + "cell_type": "markdown", + "id": "c5cdb3b0", + "metadata": {}, + "source": [ + "#### 可见性和属性装饰器" + ] + }, + { + "cell_type": "markdown", + "id": "207cad3b", + "metadata": {}, + "source": [ + "对象的属性被设置成私有(private,属性前加__)或受保护(protected,属性前加_),以避免外界直接访问这些属性。\n", + "> 为什么要不允许外界直接访问?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a32d115d", + "metadata": {}, + "outputs": [], + "source": [ + "class Student:\n", + " __slots__ = ('name','age')\n", + " def __init__(self,name,age):\n", + " self.__name = name\n", + " self.__age = age\n", + " def study(self,course_name):\n", + " print(f'{self.__name}正在学习{course_name}.')\n", + "stu = Student('王大锤',20)\n", + "stu.sex = '男' # 给stu这个对象动态添加sex属性\n", + "print(stu.sex)\n", + "stu.study('Python程序设计') # 可以间接访问,不能直接访问\n", + "print(stu.__name) # 报错'Student' object has no attribute '__name'" + ] + }, + { + "cell_type": "markdown", + "id": "82abe644", + "metadata": {}, + "source": [ + "#### 动态属性\n", + "Python在运行时可以改变其结构,属于动态语言。\n", + "可以动态为对象添加属性(有点类似于可变类型数据)" + ] + }, + { + "cell_type": "markdown", + "id": "cec875c5", + "metadata": {}, + "source": [ + "> 名称改写机制(Name Mangling)是 Python 中的一种机制,用于避免子类覆盖父类的私有属性或方法。它会将以双下划线 __ 开头但不以双下划线结尾的属性或方法名,自动改写为 _类名__属性名 的形式。 \n", + "> 名称改写的主要目的是为了实现类的封装,避免子类意外覆盖父类的私有属性或方法。\n" + ] + }, + { + "cell_type": "markdown", + "id": "b944aefb", + "metadata": {}, + "source": [ + "class Triangle(object): 这里面加不加object有什么区别 " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "391876e3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "print(Student)" + ] + }, + { + "cell_type": "markdown", + "id": "2093e7f3", + "metadata": {}, + "source": [ + "#### 继承和多态\n", + "例如Teacher类继承自Person类" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "158e54f0", + "metadata": {}, + "outputs": [], + "source": [ + "class Person:\n", + " def __init__(self,name,age):\n", + " self.name = name\n", + " self.age = age\n", + " def eat(self):\n", + " print(f'{self.name}正在吃饭。')\n", + " def sleep(self):\n", + " print(f'{self.name}正在睡觉。')\n", + "\n", + "class Teacher(Person): # Teacher类继承自Person类\n", + " def __init__(self,name,age,title): \n", + " super().__init__(name,age) \n", + " # 子类中通过super().__init__()来调用父类初始化方法\n", + " self.title = title\n", + " # 子类定义自己特有的属性和方法\n", + " def teach(self,course_name):\n", + " print(f'{self.name}{self.titel}正在讲授{course_name}.')\n" + ] + }, + { + "cell_type": "markdown", + "id": "a6374de7", + "metadata": {}, + "source": [ + "#### 面向对象编程举例" + ] + }, + { + "cell_type": "markdown", + "id": "75cb9380", + "metadata": {}, + "source": [ + "##### 例子1:扑克牌游戏\n", + "说明:简单起见,我们的扑克只有52张牌(没有大小王),游戏需要将 52 张牌发到 4 个玩家的手上,每个玩家手上有 13 张牌,按照黑桃、红心、草花、方块的顺序和点数从小到大排列,暂时不实现其他的功能。" + ] + }, + { + "cell_type": "markdown", + "id": "cc705878", + "metadata": {}, + "source": [ + "> 发现不止一个对象或者类,要考虑类之间的关系: \n", + "> - is-a(继承)\n", + "> - has-a(关联)\n", + "> - use-a(依赖) \n", + "> 以以上例子为例,因为一副扑克有(has-a)52张牌,所以扑克和牌是has-a关系(关联);因为玩家手上有(has-a)牌,而且玩家使用了(use-a)牌,所以玩家和牌之间不仅有关联关系,还有依赖关系。\n", + ">\n", + "> 疑问:分这三类有什么具体用处?\n", + ">\n", + "> 类的属性和方法: \n", + "> 牌:属性包括花色和点数\n", + "> 扑克:属性包括牌剩余牌数;方法包括被抓牌然后减少牌数\n", + "> 玩家:属性包括手里牌的张数;方法包括抓牌、排序\n", + "\n", + "5 行话理解如何设计类(非常关键) \n", + "① 圈名词 → 找类、属性 \n", + "不是所有名词都是类,现实中独立存在的实体、有自己的状态和行为、在系统中是会变化的(这种变化应该是相对复杂的,用类可以保存状态并提供操作状态的方法,这种状态的变化不是单一变量可以处理的)、会在系统中被多个对象使用(需要复用)的才可能成为类\n", + "② 圈动词 → 找方法 \n", + "③ 基于“现实世界职责”分给合适的类 \n", + "④ 让每个类只负责“它自己能做的事” \n", + "⑤ 用组合(has-a)连接类,用方法调用(use-a)产生交互\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "d5d5d6ca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Suite.SPADE:0\n", + "Suite.HEART:1\n", + "Suite.CLUB:2\n", + "Suite.DIAMOND:3\n", + "♠5\n", + "♥K\n", + "东邪:[♠2, ♠3, ♠7, ♠8, ♠10, ♠J, ♠Q, ♥9, ♣A, ♣2, ♣5, ♣6, ♦K]\n", + "西毒:[♠9, ♥A, ♥5, ♥7, ♥8, ♥Q, ♣3, ♣9, ♣Q, ♦2, ♦4, ♦7, ♦9]\n", + "南帝:[♠5, ♠6, ♠K, ♥2, ♥3, ♥10, ♥J, ♦A, ♦3, ♦5, ♦8, ♦10, ♦J]\n", + "北丐:[♠A, ♠4, ♥4, ♥6, ♥K, ♣4, ♣7, ♣8, ♣10, ♣J, ♣K, ♦6, ♦Q]\n" + ] + } + ], + "source": [ + "from enum import Enum # Python中创建枚举值要引入enum模块\n", + "\n", + "class Suite(Enum): # 新建一个Suite类来继承Enum类\n", + " \"\"\"牌花色的枚举值\"\"\"\n", + " SPADE,HEART,CLUB,DIAMOND = range(4)\n", + "\n", + "for suite in Suite: # Python中的枚举值可以迭代\n", + " print(f'{suite}:{suite.value}')\n", + "\n", + "# 定义牌这个类\n", + "# 牌类初始化时,牌一定是有指定的花色和大小\n", + "\n", + "class Card:\n", + " \"\"\"牌\"\"\"\n", + "\n", + " def __init__(self,suite,face):\n", + " self.suite = suite\n", + " self.face = face\n", + " \n", + " # __repr__(self):定义对象的开发者友好字符串表示,\n", + " # repr(obj) 或直接在交互式环境中输入对象时会调用。\n", + " def __repr__(self):\n", + " suites = '♠♥♣♦'\n", + " faces = ['','A','2','3','4','5','6',\n", + " '7','8','9','10','J','Q','K']\n", + " return f'{suites[self.suite.value]}{faces[self.face]}'\n", + " # 返回牌的花色和点数\n", + " \n", + " def __lt__(self,other):\n", + " if self.suite == other.suite:\n", + " return self.face < other.face # 花色相同比较点数大小\n", + " return self.suite.value < other.suite.value # 花色不同比较花色对应值\n", + "\n", + "card1 = Card(Suite.SPADE,5)\n", + "card2 = Card(Suite.HEART,13)\n", + "print(card1)\n", + "print(card2)\n", + "\n", + "# 定义扑克类\n", + "# 扑克类初始化时一定是指定的52张牌,\n", + "# 另外还有洗牌、发牌的方法,有还剩多少张牌的属性\n", + "import random\n", + "\n", + "class Poker:\n", + " \"\"\"扑克\"\"\"\n", + "\n", + " def __init__(self):# 52张牌构成的列表\n", + " self.cards = [Card(suite,face)\n", + " for suite in Suite\n", + " for face in range(1,14)]\n", + " self.current = 0 # 记录发牌位置的属性\n", + "\n", + " def shuffle(self):\n", + " \"\"\"洗牌\"\"\"\n", + " self.current = 0\n", + " random.shuffle(self.cards)\n", + " # 通过random模块的shuffle函数实现随机乱序\n", + " \n", + " def deal(self):\n", + " \"\"\"发牌\"\"\"\n", + " card = self.cards[self.current]\n", + " self.current += 1\n", + " return card\n", + " \n", + " @property\n", + " def has_nex(self):\n", + " \"\"\"还有没有牌可以发\"\"\"\n", + " return self.current < len(self.cards)\n", + " \n", + "# 定义玩家类\n", + "# 玩家类有摸牌、整理手牌的方法\n", + "class Player:\n", + " \"\"\"玩家\"\"\"\n", + "\n", + " def __init__(self,name):\n", + " self.name = name\n", + " self.cards = [] # 玩家手里的牌\n", + "\n", + " def get_one(self,card):\n", + " \"\"\"摸牌\"\"\"\n", + " self.cards.append(card)\n", + " \n", + " def arrange(self):\n", + " \"\"\"整理手上的牌\"\"\"\n", + " self.cards.sort()\n", + " \n", + "# 创建四个玩家,并发牌到玩家手上\n", + "poker = Poker()\n", + "poker.shuffle()\n", + "players = [Player('东邪'),Player('西毒'),Player('南帝'),Player('北丐')]\n", + "# 将牌轮流发到每个玩家手上每人13张牌\n", + "for _ in range(13):\n", + " for player in players:\n", + " player.get_one(poker.deal())\n", + "# 玩家整理手上的牌输出名字和手牌\n", + "for player in players:\n", + " player.arrange()\n", + " print(f'{player.name}:',end='')\n", + " print(player.cards)\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git "a/\345\255\246\344\271\240\347\254\224\350\256\260/git\345\267\245\344\275\234\346\265\201\347\250\213.md" "b/\345\255\246\344\271\240\347\254\224\350\256\260/git\345\267\245\344\275\234\346\265\201\347\250\213.md" new file mode 100644 index 000000000..a16b892f3 --- /dev/null +++ "b/\345\255\246\344\271\240\347\254\224\350\256\260/git\345\267\245\344\275\234\346\265\201\347\250\213.md" @@ -0,0 +1,60 @@ +## Git 工作流程 +本章节我们将为大家介绍 Git 的工作流程。 + +下图展示了 Git 的工作流程: +![Git 的工作流程](image.png) + +### 1、克隆仓库 +如果你要参与一个已有的项目,首先需要将远程仓库克隆到本地: +``` +git clone https://github.com/username/repo.git +cd repo +``` +> 问题1:如何只下载某个文件,不是克隆整个仓库 + +#### 如果确定远程为准,直接覆盖掉本地文件 +`git status`可以看未提交的修改(工作区+暂存区) +`nothing to commit,working tree clean`则为干干净净,表示无任何修改 +`git pull`只看提交记录是否一致,不管本地是否修改了文件。 +`git pull = git fetch + git merge`,git会比较本地当前分支的commit ID和远程当前分支的commit ID,如果两个ID一样,就会认为是`already up to date` +即使执行`git commit`,也是将文件在本地做了提交,需要再执行`git push origin master`才可以将本地的提交,提交到远程仓库 + +### 2、创建新分支 +为了避免直接在 main 或 master 分支上进行开发,通常会创建一个新的分支: +`git checkout -b new-feature` +### 3、工作目录 +在工作目录中进行代码编辑、添加新文件或删除不需要的文件。 +### 4、暂存文件 +将修改过的文件添加到暂存区,以便进行下一步的提交操作: +`git add filename` +或者添加所有修改的文件 +`git add .` +### 5、提交更改 +将暂存区的更改提交到本地仓库,并添加提交信息: +`git commit -m "Add new feature"` +### 6、拉取最新更改 +在推送本地更改之前,最好从远程仓库拉取最新的更改,以避免冲突: +`git pull origin main` +或者如果在新的分支上工作 +`git pull origin new-feature` +> 最新的更改,指的是最新远程仓库上面的信息吗? +### 7、推送更改 +将本地的提交推送到远程仓库: +`git push origin new-feature` +### 8、创建 Pull Request(PR) +在 GitHub 或其他托管平台上创建 Pull Request,邀请团队成员进行代码审查。PR 合并后,你的更改就会合并到主分支。 +### 9、合并更改 +在 PR 审核通过并合并后,可以将远程仓库的主分支合并到本地分支: +``` +git checkout main +git pull origin main +git merge new-feature +``` +### 10、删除分支 +如果不再需要新功能分支,可以将其删除: +`git branch -d new-feature` +或者从远程仓库删除分支: +`git push origin --delete new-feature` + +### 如果需要从github往本地下载文件怎么办, +只下载部分文件而且这些文件已经在本地了, \ No newline at end of file diff --git "a/\345\255\246\344\271\240\347\254\224\350\256\260/image.png" "b/\345\255\246\344\271\240\347\254\224\350\256\260/image.png" new file mode 100644 index 000000000..768579417 Binary files /dev/null and "b/\345\255\246\344\271\240\347\254\224\350\256\260/image.png" differ diff --git "a/\345\255\246\344\271\240\347\254\224\350\256\260/markdown\350\257\255\346\263\225.ipynb" "b/\345\255\246\344\271\240\347\254\224\350\256\260/markdown\350\257\255\346\263\225.ipynb" new file mode 100644 index 000000000..6763da46d --- /dev/null +++ "b/\345\255\246\344\271\240\347\254\224\350\256\260/markdown\350\257\255\346\263\225.ipynb" @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "44897e58", + "metadata": {}, + "source": [ + "## 一、标题(#)\n", + "### 三级标题\n", + "#### 四级标题\n", + "\n", + "## 二、段落与换行\n", + "这是第一段。(空一行=新段落)\n", + "\n", + "这是第二段(行末两个空格=换行) \n", + "换行后的内容\n", + "## 三、粗体\n", + "**粗体** \n", + "*斜体* \n", + "~~删除线~~ \n", + "也可以组合 **加粗*内部斜体*组合**\n", + "## 四、列表\n", + "无序列表: \n", + "- 项目1 \n", + "- 项目2 \n", + " -项目2.1 \n", + "\n", + "有序列表: \n", + "1. 项目1 \n", + "2. 项目2 \n", + "2.1 项目2.1 \n", + "2.2 项目2.2 \n", + "## 五、引用(>)\n", + "> 这是引用 \n", + "> 可以多行\n", + "## 六、代码\n", + "请执行 `print('Hello World')`\n", + "代码块: \n", + "```python\n", + "ded add(a,b):\n", + " return a + b\n", + "```\n", + "## 七、表格\n", + "|姓名|年龄|城市|\n", + "|------|------|------|\n", + "|张三|20|北京|\n", + "|李四|25|上海|\n", + "## 八、链接与图片\n", + "[超链接名称](http://www/baidu.com) \n", + "![超链接名称](https://www.baidu.com/img/flexible/logo/pc/result.png) \n", + "或者使用本地图片也可以\n", + "## 九、分割线(---或者***)\n", + "---\n", + "---\n", + "## 十、任务列表\n", + "- [x] 已完成任务 \n", + "- [ ] 待办任务\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git "a/\345\255\246\344\271\240\347\254\224\350\256\260/python_object_system_full.md" "b/\345\255\246\344\271\240\347\254\224\350\256\260/python_object_system_full.md" new file mode 100644 index 000000000..7dd27b44c --- /dev/null +++ "b/\345\255\246\344\271\240\347\254\224\350\256\260/python_object_system_full.md" @@ -0,0 +1,252 @@ +# Python 对象体系全景图(完整版本) + +## 📑 目录(TOC) + +- [1. Python 中的 object 是一切的根](#1-python-中的-object-是一切的根) +- [2. object → collections.abc + 行为体系](#2-object--collectionsabc-行为体系) + - [2.1 Iterable(可迭代)](#21-iterable可迭代) + - [2.2 Sequence(序列)](#22-sequence序列) + - [2.3 Set(集合)](#23-set集合) + - [2.4 Mapping(映射)](#24-mapping映射) + - [2.5 Iterator(迭代器)](#25-iterator迭代器) + - [2.6 Generator(生成器)](#26-generator生成器) + - [2.7 Hashable(可哈希)](#27-hashable可哈希) + - [2.8 Callable(可调用)](#28-callable可调用) +- [3. Python 数值体系(numbers 模块)](#3-python-数值体系numbers-模块) +- [4. I/O 类型](#4-io-类型) +- [5. 模块对象 module](#5-模块对象-module) +- [6. 类与实例体系](#6-类与实例体系) +- [7. 上下文管理器](#7-上下文管理器) +- [8. 特殊类型](#8-特殊类型) +- [9. 完整树形结构总结](#9-完整树形结构总结) +- [10. 终极总结](#10-终极总结) + +------------------------------------------------------------------------ + +# 1. Python 中的 object 是一切的根 + +Python 采用统一对象模型(Everything is an object)。 + +所有内容(int、list、dict、class、function...)都继承自 object。 + +------------------------------------------------------------------------ + +# 2. object → collections.abc 行为体系 + +collections.abc 定义了容器、序列、映射等行为规范。 + +------------------------------------------------------------------------ + +# 2.1 Iterable(可迭代) + + Iterable + ├── Container + ├── Sized + └── Sequence + +Iterable 典型类型: + +- list / tuple / dict / set\ +- str / bytes\ +- range\ +- file 对象\ +- generator + +------------------------------------------------------------------------ + +# 2.2 Sequence(序列) + +序列 = 有序 + 可索引。 + + Sequence + ├── list(可变) + ├── tuple(不可变) + ├── range(不可变) + ├── str(不可变字符序列) + └── bytes(不可变字节序列) + +可变序列: + + MutableSequence + └── list + +------------------------------------------------------------------------ + +# 2.3 Set(集合) + + Set + ├── set(可变) + └── frozenset(不可变) + +------------------------------------------------------------------------ + +# 2.4 Mapping(映射) + + Mapping + ├── dict(可变) + └── MappingProxyType(只读映射) + +------------------------------------------------------------------------ + +# 2.5 Iterator(迭代器) + + Iterator + ├── list_iterator + ├── tuple_iterator + ├── range_iterator + └── dict_*iterator + +只要实现了 **next** 和 **iter**,就是迭代器。 + +------------------------------------------------------------------------ + +# 2.6 Generator(生成器) + + Generator + └── generator(yield) + +------------------------------------------------------------------------ + +# 2.7 Hashable(可哈希) + +可作为字典 key 或 set 元素。 + + Hashable + ├── int + ├── float + ├── str + ├── bytes + ├── tuple(内部全可哈希) + └── frozenset + +------------------------------------------------------------------------ + +# 2.8 Callable(可调用) + +能执行 "()" 的就是 Callable。 + + Callable + ├── function + ├── method + ├── class(可实例化) + └── 实现 __call__ 的对象 + +示例: + +``` python +class A: + def __call__(self): + print("callable") +``` + +------------------------------------------------------------------------ + +# 3. Python 数值体系(numbers 模块) + + Number + ├── Integral → int + ├── Real → float + ├── Complex → complex + └── Rational → Fraction + +------------------------------------------------------------------------ + +# 4. I/O 类型 + + TextIOWrapper(文本文件) + BufferedReader + BufferedWriter + BytesIO + StringIO + +------------------------------------------------------------------------ + +# 5. 模块对象 module + + module(如 math、os、sys) + +模块也是对象。 + +------------------------------------------------------------------------ + +# 6. 类与实例体系 + + type(类的类型) + └── class A + └── A 实例对象 + +------------------------------------------------------------------------ + +# 7. 上下文管理器 + +只要实现了: + + __enter__() + __exit__() + +即可用于 with 语句。 + +典型例子:文件、锁、数据库连接等。 + +------------------------------------------------------------------------ + +# 8. 特殊类型 + + NoneType(None) + bool + ellipsis(...) + NotImplementedType + memoryview + bytearray(可变字节序列) + +------------------------------------------------------------------------ + +# 9. 完整树形结构总结 + + object + ├── Iterable + │ ├── Sequence(list, tuple, range, str, bytes) + │ ├── MutableSequence(list) + │ ├── Set(set, frozenset) + │ ├── Mapping(dict) + │ ├── Iterator(所有迭代器) + │ └── Generator + │ + ├── Hashable(int, str, tuple, frozenset, bytes) + │ + ├── Callable(函数、类、方法、__call__ 对象) + │ + ├── Number(int, float, complex, Fraction) + │ + ├── IO(文件对象、缓冲区) + │ + ├── module(math, os...) + │ + ├── type(所有类的类型) + │ + ├── 自定义 class 与实例 + │ + └── 特殊类型(NoneType, bool, ellipsis 等) + +------------------------------------------------------------------------ + +# 10. 终极总结 + +Python 的体系本质是: + +> **行为驱动(Protocol / ABC)+ 鸭子类型(Duck Typing)**\ +> 只要对象实现了对应方法(协议),就被视为该类。 + +例如: + +- 有 `__iter__` → Iterable\ +- 有 `__getitem__` → Sequence 行为\ +- 有 `__next__` → Iterator\ +- 有 `__call__` → Callable + +Python 是通过行为判断,而不是类型名字判断。 + +------------------------------------------------------------------------ + +(全文结束) diff --git "a/\345\255\246\344\271\240\347\254\224\350\256\260/\345\255\246\344\271\240\346\226\271\346\263\225\351\227\256\351\242\230.md" "b/\345\255\246\344\271\240\347\254\224\350\256\260/\345\255\246\344\271\240\346\226\271\346\263\225\351\227\256\351\242\230.md" new file mode 100644 index 000000000..e7528c2cd --- /dev/null +++ "b/\345\255\246\344\271\240\347\254\224\350\256\260/\345\255\246\344\271\240\346\226\271\346\263\225\351\227\256\351\242\230.md" @@ -0,0 +1,270 @@ + # 什么是“一句话总结”: + - 它是什么 + - 为什么存在(解决什么问题?) + - 什么时候用 + + +# 我的Python越学越乱的原因: +- 记得是“细节”,而不是“框架” +- 我学到的每一个知识点在脑中没有一个“抽象层级” +- 我不知道这个知识点解决什么问题 +- 新出现的类型、新的语法,对我来说都是孤立的 + + +# 核心观念:Python 的所有东西,都可以归为三类 +① 数据 +② 行为(函数) +③ 容器 + 协议(数据如何被操作) + +我看到的所有“新类型”“新用法”其实都只是: +- 一种新的数据结构 +- 一个函数/方法 +- 一种操作规则(协议,如迭代、上下文、可哈希、序列类型) +- 一个标准库里封装好的工具 + +# Python 三大核心概念:数据、行为、协议 + +本文件系统性地解释 Python 世界中所有“看似无穷无尽的知识点”背后的统一抽象模型。 +帮助你用底层原理建立“不会乱、不怕新知识”的学习体系。 + +--- + +# 📍 第一类:数据(Data) +Python 的一切基础都是“数据”。 +你看到的所有类型,本质上都是 **数据结构**。 + +## 🧩 常见基础数据类型(一句话总结) +| 数据类型 | 一句话总结 | +|---------|------------| +| **int** | 一个整数值 | +| **float** | 一个小数 | +| **str** | 一段文本(不可变) | +| **list** | 可变序列 | +| **tuple** | 不可变序列 | +| **dict** | 哈希表,用 key 查 value | +| **set** | 去重 + 集合运算 | +| **bytes** | 二进制序列 | +| **bool** | True / False | +| **class** | 用户自定义的数据结构 | + +--- + +## 🧩 你未来会看到的“新类型”(其实也是数据) +例如: + +- datetime +- Fraction +- Decimal +- pathlib.Path +- re.Match +- MySQLCursor +- Response(requests) +- BeautifulSoup +- numpy.ndarray +- pandas.DataFrame + +它们都不是“新奇怪物”,它们都是: + +> Python 内置或第三方库定义的 **新的数据结构(结构不同,本质相同)** + +### ✔ 结论 +**所有“新数据类型”都是“数据”,不是新概念,只是新结构。** + +--- + +# 📍 第二类:行为(Function) +数据能做什么,由“行为”决定。 + +行为的统一定义: + +## ⭐ 行为 = 函数 + 方法(绑定到对象的函数) + +--- + +## 🎯 示例(你看到的一切操作,都是行为) +| 代码 | 类型 | 说明 | +|------|------|-------| +| `len(a)` | 函数 | 获取长度 | +| `a.append(3)` | 方法 | list 的行为 | +| `d.get("name")` | 方法 | dict 的行为 | +| `re.match()` | 函数 | 正则匹配 | +| `random.randint()` | 函数 | 取随机数 | + +本质上它们都是: + +> 输入数据 → 行为处理 → 输出结果 +> (方法还会改变对象内部状态) + +--- + +## ✔ 为什么这能消除你的焦虑? +当你知道: + +- list 的操作是 list 定义的行为 +- dict 的操作是 dict 定义的行为 +- 库里的方法是库的作者定义的行为 + +你看到“新方法、新函数、新 API” +就不会觉得那是“新知识点”,它只是“行为”。 + +--- + +# 📍 第三类:容器 + 协议(规则) +这是 Python 最强大也最容易让初学者困惑的部分。 + +--- + +# 1️⃣ 什么是容器? +容器就是“能装数据的结构”。 + +常见容器: + +- list +- tuple +- dict +- set +- generator +- iterator +- file +- pandas.DataFrame +- numpy.ndarray + +它们结构不同,但本质相同: +**装数据 + 对外提供统一操作行为(协议)** + +--- + +# 2️⃣ 什么是协议? +协议 ≠ 网络协议 +协议 = **规定对象必须具备的能力(钩子方法)** + +只要该能力被实现,对象就能表现出某种“行为”。 + +--- + +# 🔥 Python 常见协议(必须掌握) + +## ① 可迭代协议(Iterable) +只要对象实现: + +``` +__iter__() +``` + +它就能: + +- 被 for 循环 +- 被 list() 转换 +- 被展开:`*obj` +- 被 sum()、max() 等函数使用 + +### 🔥 所有这些都能 for,因为它们实现了 iterable: +- list +- tuple +- dict +- str +- range +- pandas.Series +- generator + +它们长得不一样,但行为一样,是因为遵守了 **同一个协议**。 + +--- + +## ② 上下文管理协议(Context Manager) +只要对象实现: + +``` +__enter__() +__exit__() +``` + +它就能被 `with` 使用。 + +### 这些都能用 with: +- 文件对象 +- 数据库连接 +- 锁 +- Selenium 浏览器 +- Requests Session +- TensorFlow Session +- contextlib 生成的对象 + +它们毫不相关,却都能: + +```python +with obj: + ... +``` + +因为它们遵守同一个协议。 + +--- + +## ③ 可调用协议(Callable) +如果一个对象实现: + +``` +__call__() +``` + +那么它就可以作为函数调用: + +```python +obj() +``` + +Python 的装饰器、回调机制、类实例当函数,都是用这个协议。 + +--- + +## ④ 数字协议(算术运算) +对象实现这些方法后,就能进行数学运算: + +``` +__add__() → + +__sub__() → - +__mul__() → * +``` + +numpy / pandas 的底层,就是依靠这些协议。 + +--- + +## ⑤ 序列协议(像数组一样) +只要实现: + +``` +__getitem__() +__len__() +``` + +它就能: + +- 被索引:`obj[0]` +- 被切片:`obj[1:3]` +- 被遍历 + +--- + +# 📌 最终总结(非常关键) + +## ⭐ Python 所有看似复杂的东西,都能归类为三件事: + +### **① 数据(Data)—— 类型本质是数据结构** +### **② 行为(Function/Method)—— 数据能做什么** +### **③ 协议(Protocol)—— 对象具备哪些能力** + +--- + +# ✔ 这意味着: + +- 新类型?→ 属于“数据” +- 新方法?→ 属于“行为” +- 能被 for?→ 遵守迭代协议 +- 能被 with?→ 遵守上下文协议 +- 能被调用?→ 遵守可调用协议 + +所有新东西都“有位置”,不会让你困惑。 + +---