├── .gitattributes ├── .github └── workflows │ └── deploy.yml ├── .gitignore ├── LICENSE ├── README.md ├── code ├── code.py ├── main.py └── mod │ ├── __init__.py │ └── main.py ├── docs ├── css │ └── chunk-vendors.4e4765ff.css ├── favicon.png ├── img │ └── swipe.svg ├── index.html ├── js │ ├── chunk-vendors.js │ ├── chunk-vendors.js.LICENSE.txt │ ├── index.js │ └── index.js.LICENSE.txt └── style.css ├── index.md ├── main.ipynb ├── public ├── favicon.png └── style.css ├── slide_dark.pdf ├── slide_light.pdf ├── test.txt ├── test.zip └── test2.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | *.md linguist-documentation=false linguist-detectable=true 2 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to slides repo 2 | 3 | on: push 4 | 5 | jobs: 6 | docs: 7 | runs-on: ubuntu-latest 8 | name: copy docs folder to slides repo 9 | 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@master 13 | 14 | - name: Push update file to slides repo 15 | uses: dmnemec/copy_file_to_another_repo_action@3fe42250d47e0764da9de9939b151b09a26e5857 16 | env: 17 | API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} 18 | with: 19 | source_file: 'docs/.' 20 | destination_repo: 'TonyCrane/slides' 21 | destination_branch: 'master' 22 | destination_folder: 'PythonLecture' 23 | user_email: 'tonycrane@foxmail.com' 24 | user_name: 'TonyCrane' 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __pycache__/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution 4.0 International Public License 58 | 59 | By exercising the Licensed Rights (defined below), You accept and agree 60 | to be bound by the terms and conditions of this Creative Commons 61 | Attribution 4.0 International Public License ("Public License"). To the 62 | extent this Public License may be interpreted as a contract, You are 63 | granted the Licensed Rights in consideration of Your acceptance of 64 | these terms and conditions, and the Licensor grants You such rights in 65 | consideration of benefits the Licensor receives from making the 66 | Licensed Material available under these terms and conditions. 67 | 68 | 69 | Section 1 -- Definitions. 70 | 71 | a. Adapted Material means material subject to Copyright and Similar 72 | Rights that is derived from or based upon the Licensed Material 73 | and in which the Licensed Material is translated, altered, 74 | arranged, transformed, or otherwise modified in a manner requiring 75 | permission under the Copyright and Similar Rights held by the 76 | Licensor. For purposes of this Public License, where the Licensed 77 | Material is a musical work, performance, or sound recording, 78 | Adapted Material is always produced where the Licensed Material is 79 | synched in timed relation with a moving image. 80 | 81 | b. Adapter's License means the license You apply to Your Copyright 82 | and Similar Rights in Your contributions to Adapted Material in 83 | accordance with the terms and conditions of this Public License. 84 | 85 | c. Copyright and Similar Rights means copyright and/or similar rights 86 | closely related to copyright including, without limitation, 87 | performance, broadcast, sound recording, and Sui Generis Database 88 | Rights, without regard to how the rights are labeled or 89 | categorized. For purposes of this Public License, the rights 90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 91 | Rights. 92 | 93 | d. Effective Technological Measures means those measures that, in the 94 | absence of proper authority, may not be circumvented under laws 95 | fulfilling obligations under Article 11 of the WIPO Copyright 96 | Treaty adopted on December 20, 1996, and/or similar international 97 | agreements. 98 | 99 | e. Exceptions and Limitations means fair use, fair dealing, and/or 100 | any other exception or limitation to Copyright and Similar Rights 101 | that applies to Your use of the Licensed Material. 102 | 103 | f. Licensed Material means the artistic or literary work, database, 104 | or other material to which the Licensor applied this Public 105 | License. 106 | 107 | g. Licensed Rights means the rights granted to You subject to the 108 | terms and conditions of this Public License, which are limited to 109 | all Copyright and Similar Rights that apply to Your use of the 110 | Licensed Material and that the Licensor has authority to license. 111 | 112 | h. Licensor means the individual(s) or entity(ies) granting rights 113 | under this Public License. 114 | 115 | i. Share means to provide material to the public by any means or 116 | process that requires permission under the Licensed Rights, such 117 | as reproduction, public display, public performance, distribution, 118 | dissemination, communication, or importation, and to make material 119 | available to the public including in ways that members of the 120 | public may access the material from a place and at a time 121 | individually chosen by them. 122 | 123 | j. Sui Generis Database Rights means rights other than copyright 124 | resulting from Directive 96/9/EC of the European Parliament and of 125 | the Council of 11 March 1996 on the legal protection of databases, 126 | as amended and/or succeeded, as well as other essentially 127 | equivalent rights anywhere in the world. 128 | 129 | k. You means the individual or entity exercising the Licensed Rights 130 | under this Public License. Your has a corresponding meaning. 131 | 132 | 133 | Section 2 -- Scope. 134 | 135 | a. License grant. 136 | 137 | 1. Subject to the terms and conditions of this Public License, 138 | the Licensor hereby grants You a worldwide, royalty-free, 139 | non-sublicensable, non-exclusive, irrevocable license to 140 | exercise the Licensed Rights in the Licensed Material to: 141 | 142 | a. reproduce and Share the Licensed Material, in whole or 143 | in part; and 144 | 145 | b. produce, reproduce, and Share Adapted Material. 146 | 147 | 2. Exceptions and Limitations. For the avoidance of doubt, where 148 | Exceptions and Limitations apply to Your use, this Public 149 | License does not apply, and You do not need to comply with 150 | its terms and conditions. 151 | 152 | 3. Term. The term of this Public License is specified in Section 153 | 6(a). 154 | 155 | 4. Media and formats; technical modifications allowed. The 156 | Licensor authorizes You to exercise the Licensed Rights in 157 | all media and formats whether now known or hereafter created, 158 | and to make technical modifications necessary to do so. The 159 | Licensor waives and/or agrees not to assert any right or 160 | authority to forbid You from making technical modifications 161 | necessary to exercise the Licensed Rights, including 162 | technical modifications necessary to circumvent Effective 163 | Technological Measures. For purposes of this Public License, 164 | simply making modifications authorized by this Section 2(a) 165 | (4) never produces Adapted Material. 166 | 167 | 5. Downstream recipients. 168 | 169 | a. Offer from the Licensor -- Licensed Material. Every 170 | recipient of the Licensed Material automatically 171 | receives an offer from the Licensor to exercise the 172 | Licensed Rights under the terms and conditions of this 173 | Public License. 174 | 175 | b. No downstream restrictions. You may not offer or impose 176 | any additional or different terms or conditions on, or 177 | apply any Effective Technological Measures to, the 178 | Licensed Material if doing so restricts exercise of the 179 | Licensed Rights by any recipient of the Licensed 180 | Material. 181 | 182 | 6. No endorsement. Nothing in this Public License constitutes or 183 | may be construed as permission to assert or imply that You 184 | are, or that Your use of the Licensed Material is, connected 185 | with, or sponsored, endorsed, or granted official status by, 186 | the Licensor or others designated to receive attribution as 187 | provided in Section 3(a)(1)(A)(i). 188 | 189 | b. Other rights. 190 | 191 | 1. Moral rights, such as the right of integrity, are not 192 | licensed under this Public License, nor are publicity, 193 | privacy, and/or other similar personality rights; however, to 194 | the extent possible, the Licensor waives and/or agrees not to 195 | assert any such rights held by the Licensor to the limited 196 | extent necessary to allow You to exercise the Licensed 197 | Rights, but not otherwise. 198 | 199 | 2. Patent and trademark rights are not licensed under this 200 | Public License. 201 | 202 | 3. To the extent possible, the Licensor waives any right to 203 | collect royalties from You for the exercise of the Licensed 204 | Rights, whether directly or through a collecting society 205 | under any voluntary or waivable statutory or compulsory 206 | licensing scheme. In all other cases the Licensor expressly 207 | reserves any right to collect such royalties. 208 | 209 | 210 | Section 3 -- License Conditions. 211 | 212 | Your exercise of the Licensed Rights is expressly made subject to the 213 | following conditions. 214 | 215 | a. Attribution. 216 | 217 | 1. If You Share the Licensed Material (including in modified 218 | form), You must: 219 | 220 | a. retain the following if it is supplied by the Licensor 221 | with the Licensed Material: 222 | 223 | i. identification of the creator(s) of the Licensed 224 | Material and any others designated to receive 225 | attribution, in any reasonable manner requested by 226 | the Licensor (including by pseudonym if 227 | designated); 228 | 229 | ii. a copyright notice; 230 | 231 | iii. a notice that refers to this Public License; 232 | 233 | iv. a notice that refers to the disclaimer of 234 | warranties; 235 | 236 | v. a URI or hyperlink to the Licensed Material to the 237 | extent reasonably practicable; 238 | 239 | b. indicate if You modified the Licensed Material and 240 | retain an indication of any previous modifications; and 241 | 242 | c. indicate the Licensed Material is licensed under this 243 | Public License, and include the text of, or the URI or 244 | hyperlink to, this Public License. 245 | 246 | 2. You may satisfy the conditions in Section 3(a)(1) in any 247 | reasonable manner based on the medium, means, and context in 248 | which You Share the Licensed Material. For example, it may be 249 | reasonable to satisfy the conditions by providing a URI or 250 | hyperlink to a resource that includes the required 251 | information. 252 | 253 | 3. If requested by the Licensor, You must remove any of the 254 | information required by Section 3(a)(1)(A) to the extent 255 | reasonably practicable. 256 | 257 | 4. If You Share Adapted Material You produce, the Adapter's 258 | License You apply must not prevent recipients of the Adapted 259 | Material from complying with this Public License. 260 | 261 | 262 | Section 4 -- Sui Generis Database Rights. 263 | 264 | Where the Licensed Rights include Sui Generis Database Rights that 265 | apply to Your use of the Licensed Material: 266 | 267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 268 | to extract, reuse, reproduce, and Share all or a substantial 269 | portion of the contents of the database; 270 | 271 | b. if You include all or a substantial portion of the database 272 | contents in a database in which You have Sui Generis Database 273 | Rights, then the database in which You have Sui Generis Database 274 | Rights (but not its individual contents) is Adapted Material; and 275 | 276 | c. You must comply with the conditions in Section 3(a) if You Share 277 | all or a substantial portion of the contents of the database. 278 | 279 | For the avoidance of doubt, this Section 4 supplements and does not 280 | replace Your obligations under this Public License where the Licensed 281 | Rights include other Copyright and Similar Rights. 282 | 283 | 284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 285 | 286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 296 | 297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 306 | 307 | c. The disclaimer of warranties and limitation of liability provided 308 | above shall be interpreted in a manner that, to the extent 309 | possible, most closely approximates an absolute disclaimer and 310 | waiver of all liability. 311 | 312 | 313 | Section 6 -- Term and Termination. 314 | 315 | a. This Public License applies for the term of the Copyright and 316 | Similar Rights licensed here. However, if You fail to comply with 317 | this Public License, then Your rights under this Public License 318 | terminate automatically. 319 | 320 | b. Where Your right to use the Licensed Material has terminated under 321 | Section 6(a), it reinstates: 322 | 323 | 1. automatically as of the date the violation is cured, provided 324 | it is cured within 30 days of Your discovery of the 325 | violation; or 326 | 327 | 2. upon express reinstatement by the Licensor. 328 | 329 | For the avoidance of doubt, this Section 6(b) does not affect any 330 | right the Licensor may have to seek remedies for Your violations 331 | of this Public License. 332 | 333 | c. For the avoidance of doubt, the Licensor may also offer the 334 | Licensed Material under separate terms or conditions or stop 335 | distributing the Licensed Material at any time; however, doing so 336 | will not terminate this Public License. 337 | 338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 339 | License. 340 | 341 | 342 | Section 7 -- Other Terms and Conditions. 343 | 344 | a. The Licensor shall not be bound by any additional or different 345 | terms or conditions communicated by You unless expressly agreed. 346 | 347 | b. Any arrangements, understandings, or agreements regarding the 348 | Licensed Material not stated herein are separate from and 349 | independent of the terms and conditions of this Public License. 350 | 351 | 352 | Section 8 -- Interpretation. 353 | 354 | a. For the avoidance of doubt, this Public License does not, and 355 | shall not be interpreted to, reduce, limit, restrict, or impose 356 | conditions on any use of the Licensed Material that could lawfully 357 | be made without permission under this Public License. 358 | 359 | b. To the extent possible, if any provision of this Public License is 360 | deemed unenforceable, it shall be automatically reformed to the 361 | minimum extent necessary to make it enforceable. If the provision 362 | cannot be reformed, it shall be severed from this Public License 363 | without affecting the enforceability of the remaining terms and 364 | conditions. 365 | 366 | c. No term or condition of this Public License will be waived and no 367 | failure to comply consented to unless expressly agreed to by the 368 | Licensor. 369 | 370 | d. Nothing in this Public License constitutes or may be interpreted 371 | as a limitation upon, or waiver of, any privileges and immunities 372 | that apply to the Licensor or You, including from the legal 373 | processes of any jurisdiction or authority. 374 | 375 | 376 | ======================================================================= 377 | 378 | Creative Commons is not a party to its public licenses. 379 | Notwithstanding, Creative Commons may elect to apply one of its public 380 | licenses to material it publishes and in those instances will be 381 | considered the “Licensor.” The text of the Creative Commons public 382 | licenses is dedicated to the public domain under the CC0 Public Domain 383 | Dedication. Except for the limited purpose of indicating that material 384 | is shared under a Creative Commons public license or as otherwise 385 | permitted by the Creative Commons policies published at 386 | creativecommons.org/policies, Creative Commons does not authorize the 387 | use of the trademark "Creative Commons" or any other trademark or logo 388 | of Creative Commons without its prior written consent including, 389 | without limitation, in connection with any unauthorized modifications 390 | to any of its public licenses or any other arrangements, 391 | understandings, or agreements concerning use of licensed material. For 392 | the avoidance of doubt, this paragraph does not form part of the public 393 | licenses. 394 | 395 | Creative Commons may be contacted at creativecommons.org. 396 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PythonLecture 2 | 3 | Slide, notebook and code of TonyCrane's Python Lecture on BiliBili. 4 | 5 | - slide: https://slides.tonycrane.cc/PythonLecture 6 | - pdf: [slide_light.pdf](https://github.com/TonyCrane/PythonLecture/blob/master/slide_light.pdf) [slide_dark.pdf](https://github.com/TonyCrane/PythonLecture/blob/master/slide_dark.pdf) 7 | - notebook: [main.ipynb](https://github.com/TonyCrane/PythonLecture/blob/master/main.ipynb) 8 | - record: https://www.bilibili.com/video/BV13Z4y1h7x5/ 9 | 10 | ## View this slide 11 | 12 | https://slides.tonycrane.cc/PythonLecture 13 | 14 | Please open it on computer instead of mobile device. 15 | 16 | Usage: 17 | - Page: ↑/↓/←/→ Space Home End 18 | - Fullscreen: F 19 | - Overview: -/+ 20 | 21 | ## Build this slide 22 | 23 | 1. Install `nodeppt` via `npm` 24 | 25 | ```sh 26 | $ npm install -g nodeppt 27 | ``` 28 | 2. Start local server to preview 29 | 30 | ```sh 31 | $ nodeppt serve index.md 32 | ``` 33 | 3. Build slide 34 | 35 | ```sh 36 | $ nodeppt build index.md 37 | ``` 38 | 39 | ## License 40 | Under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/) -------------------------------------------------------------------------------- /code/code.py: -------------------------------------------------------------------------------- 1 | """ 2 | an example module 3 | """ 4 | 5 | print("hello from code") 6 | 7 | def func(a, b): 8 | print(a, b) 9 | 10 | def func1(a, b): 11 | print(b, a) 12 | 13 | if __name__ == "__main__": 14 | func(3, 4) -------------------------------------------------------------------------------- /code/main.py: -------------------------------------------------------------------------------- 1 | # import code 2 | # from code import func 3 | # from code import * 4 | import code as cd 5 | 6 | cd.func(1, 2) 7 | cd.func1(2, 1) 8 | 9 | def func2(a, b): 10 | print(a * b) 11 | 12 | func2(1, 2) 13 | 14 | # import mod 15 | from mod import * 16 | 17 | func2(1, 2) -------------------------------------------------------------------------------- /code/mod/__init__.py: -------------------------------------------------------------------------------- 1 | print("hello from mod") 2 | 3 | from .main import func2 -------------------------------------------------------------------------------- /code/mod/main.py: -------------------------------------------------------------------------------- 1 | def func2(a, b): 2 | print(a + b) -------------------------------------------------------------------------------- /docs/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/PythonLecture/888153c7012ed202b828900229a67cd1fc057a3b/docs/favicon.png -------------------------------------------------------------------------------- /docs/img/swipe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 45 | 46 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Python 基础教学 - By TonyCrane

Python 基础教学


By @鹤翔万里(TonyCrane)

Github 直播回放

←/→ Space Home End 翻页

前言


  • 这次的教学面向没有学过 python 的人,不论有没有编程基础都可以听懂
  • 这里说的东西有些只是为了更好的理解,可能并不严谨,请不要完全听信(免责声明

为什么讲 python


  • manim 动画引擎的基础

  manim 是用 python 编写的库,使用需要有 python 的基础知识(不然会被我劝退.jpg

  • 易用易学、作为工具

  python 这个语言很易学,特别是对于有编程基础的人(几乎直接上手)。所以有些教程、课程其实过于冗余

  • 大学某些课程、老师会默认你会

什么是 python


  •  解释性的脚本语言

      通过解释器来直接运行,不需要编译链接成二进制文件

  •  动态类型语言

      类型在运行时确定,不需要通过代码明文规定

  •  面向对象语言

      python 中一切皆对象

  •  ...

怎么装 python


  • 装的是什么?
    • 是一个 python 解释器,以及运行需要的环境
  • 怎么装?
  • 装什么版本?
    • 两个大版本,2.* 和 3.*,差别较大,建议 3.*
    • 一些小版本,3.6 及之前不推荐,3.7 3.8 稳定,3.9 3.10 完善中,3.11 预览中
    • 细分版本,选择最新,3.7.13、3.8.13、3.9.12、3.10.4
    • conda 不必担心版本,默认 3.9,可以通过创建虚拟环境来使用不同版本

怎么编写、运行 python


  • 怎么用 python?
    • 记住你下载的是一个解释器,建议通过命令行运行 python code.py
  • 什么是命令行?
    • 通过输入命令来通知电脑执行某指令、或者运行某程序
    • Windows:cmd、Powershell -> 单独运行 / Windows Terminal /...
    • macOS:zsh、... -> 终端 / iTerm /...
    • Linux:bash、zsh、... -> 终端 / ...
  • 用什么写代码?
    • 记住你编写的只是一个 .py 作为扩展名的文本文件 只要文本编辑器都可以写
    • 记事本、自带 IDLE、word
    • Notepad++、Sublime Text
    • VSCode(Visual Studio Code,不是 VS)code.visualstudio.com
    • Pycharm(Community Edition 就够用)jetbrains.com/pycharm

Hello world!


print("Hello world!")
  2 | 

变量


  • 给一个内容绑定一个标签即变量名(注意请不要认为变量类似一个“盒子”)
  • 通过 = 来定义变量,变量名 = 内容
  • 动态类型,不需要规定类型(可以通过 变量名: 类型 = 内容 来进行类型标注)
  • 变量名
    • 只能包含字母、数字、下划线、中文,不能有空格和其它符号
    • 只能以字母、下划线开头,不能以数字开头,而且大小写敏感
    • 不能用关键字(例如 if def 等)作为变量名,不推荐使用内置函数名作为变量名
    • 清晰明确、风格统一
    • 全大写一般表示常量、不建议使用双下划线开头或者开头结尾、不建议使用 _ 作为变量名

数字与运算


  • 1 是整数,1. 是浮点数
  • 整数与浮点数转换
    • int(...):向 0 舍入
    • round(...):向偶舍入(四舍六入五凑偶,可以当成四舍五入)
    • math.floor(...)、math.ceil(...):下取整、上取整(需要 import math)
  • 运算
    • + - * 加减乘,左右都是整数结果也是整数,有浮点数结果就是浮点数
    • / 除法,结果是浮点数(即使可以整除)
    • // 整除,结果是整数,向下取整
    • % 取模,a % b == a - (a//b)*b(和 c 的行为不一致)
    • ** 乘方,可以是浮点数,比如 a ** 0.5 表示开根号
    • pow(a, b, mod):也是乘方,mod 可以省略,如果有 mod 则对结果取模,如果 mod 为 -1 则计算乘法逆元
    • 更多运算通过 math、numpy、scipy 等包来进行

复数类型


  • python 中内置了复数类型,1+2j 形式就表示一个复数,其中 j 即虚数单位 i
  • 或者使用 complex(实部, 虚部) 形式定义复数
  • 可以进行复数的加减乘除运算
  • 属性与方法
    • c.real:实部
    • c.imag:虚部
    • c.conjugate():返回共轭复数

字符串


  • 单引号 '...',双引号 "...",三引号 '''...''' """..."""(可以内部换行)
  • \n 换行,\t 制表符,\r 回车,' 单引号," 双引号,\\ 斜杠(只打一个 \ 会出问题),……
  • 前缀
    • r-string:r"...",引号中不进行转义,即一个 \ 就代表斜杠字符本身
    • f-string:f"...",格式化字符串
    • b-string:b"...",将字符串转为 bytes,只能包含 ASCII 字符
  • 常用方法
    • 拼接:直接将字符串“相加”
    • "...".upper()、"...".lower():转为全大写、全小写
    • "...".title():单词首字母大写
    • "...".strip():删除字符串首尾空白(包含空格和制表符)
    • "...".lstrip()、"...".rstrip():删除左、右端空白
    • "...".split(c):根据字符 c 来拆分字符串得到列表,默认拆分空白

f-string


  • 格式化字符串方式:"..." % ...,"...".format(...),f"..."
  • 字符串内大括号括起来的计算后转为字符串填入 f"...{...}..."
  • 如果字符串要用大括号原始字符要写两个 f"...{{..."
  • 格式化(在填入内容后面加冒号 f"...{表达式:格式}...")
    • 宽度填充::[填充字符][对齐方式][宽度],< 左对齐,> 右对齐,^ 居中
    • 字符截断::[...].n,只显示字符串的前 n 个字符
    • 数值符号::+ 正数加正号、负数加负号,:- 原样,: (空格)正数加空格、负数加负号
    • 数值精度::[宽度][分隔符(,_)].[精度]f,没有精度默认为 6
    • 进制显示:x 小写十六进制,X 大写十六进制,o 八进制,b 二进制,加 # 显示前缀

字节类型


  • 类似字符串,但存储的是字节的值,更像列表,显示为 b"..." 只是更加易读而已
  • b"..." 则表示字节类型,其中只能包含 ASCII 字符和 \x.. 表示的十六进制数
  • 与字符串转换
    • "...".encode(encoding) 根据 encoding 编码字符串,默认 UTF-8
    • bytes_obj.decode(encoding) 根据 encoding 解码字节序列,解码失败会报错
    • bytes("...", encoding) 也是根据 encoding 编码字符串
    • 不要使用 str(b"...") 来将字节序列转为字符串

布尔类型


  • True 和 False,记住首字母大写
  • 用 bool(...) 来转换,如果是数字则非零都是 True,如果是字符串则非空都是 True
  • 运算
    • 可以使用 & | 来表示与和或(但并不会短路)
    • 一般使用 and or not 进行与/或/非运算(会短路)

注释


  • 单行注释一个 #
  • 严格上并没有多行注释,但可以用 """ 字符串来代替(因为这样不影响运行)

列表


  • 类似其它语言的数组,但是功能更多,而且内部元素不要求同一类型
  • 方括号 [] 表示列表,元素用逗号分隔
  • 索引(即下标)从 0 开始计数,lst[n] 即表示访问第 n+1 个元素
  • 索引可以是负数,负数即表示倒数,例 lst[-2] 表示倒数第二个元素
  • 切片(获取列表中的一部分值)
    • lst[a:b]:从 lst[a] 到 lst[b-1] 的列表
    • lst[:b]:从开头到 lst[b-1] 的列表
    • lst[a:]:从 lst[a] 到结尾的列表
    • lst[:]:表示整个列表(拷贝一份)
    • lst[a:b:c]:从 lst[a] 到 lst[b-1] 每 c 个(即步长)取一个形成的列表
    • c 可以是负数,此时需要 a > b 才能获取到值
    • 有步长时若省略 a、b 记得不要省略冒号,例 lst[::-1] 表示列表倒序

列表操作


  • 修改元素:直接通过索引/切片,然后等号赋值
  • 有栈的功能
    • lst.append(...) 在列表末尾加入元素
    • lst.pop() 弹出列表末尾元素并返回
  • 任意位置插入弹出
    • lst.insert(i, x) 在索引 i 的位置插入 x,后面依次后移
    • lst.pop(i) 弹出索引 i 位置的元素,后面依次前移
  • 列表拼接
    • 直接相加,不改变原列表,得到新的列表
    • lst.extend([...]),把一个列表接到当前列表后面
  • 根据值删除元素
    • lst.remove(value) 删除第一个值为 value 的元素

列表操作


  • 排序列表
    • lst.sort() 永久排序(即排序后赋值给当前列表)
    • sorted(lst) 临时排序,返回排序好的新列表
    • 默认从小到大,如果传入 reverse=True 则从大到小
  • 反转列表
    • lst.reverse() 永久反转(意义同上)
    • lst[::-1] 返回反转的列表(利用前面说到的切片)
  • 统计操作
    • len(lst) 得到列表的长度
    • sum(lst) 得到列表的元素和(本质上是将 start 参数和每个元素依次相加)
      • 可以传入 start 参数用来指定加和的起始值
    • max(lst) 得到列表中的最大值
    • min(lst) 得到列表中的最小值

元组


  • 可以看成元素不可变的列表,内部也可以包含不同类型的元素
  • 括号表示元组,内部元素间用逗号分隔
  • 可以使用和列表一样的方法来读取元素,但并不能修改
  • 当只有一个元素的时候要写成 (a,) 而不是 (a)(后者是单个值)
  • 可以使用 tuple(...) 来将可迭代对象(列表、字符串等)转为元组
  • 元组并不能保证元素完全不可变
    • 避免在元组中存放可变元素

集合


  • 大括号括起来,内部元素间用逗号分隔,会自动去重
  • 可用 set(...) 来将可迭代对象转为元组,自动去重
  • 集合中不能包含列表等不可 hash 化的元素
  • 修改
    • s.add(...) 来加入一个元素
    • s.remove(...) 删除一个元素,如果没有会抛出异常
    • s.discard(...) 来删除一个元素,如果没有则忽略
  • 运算
    • s1 & s2、s1 | s2、s1 - s2 交集、并集、差集
    • s1 ^ s2 对称差集

字典


  • 存储键值对,也是大括号括起来,不过逗号分隔的是键值对 {key: value, ...}
  • {} 是空字典而不是空集合
  • 通过 d[key] 来访问字典中 key 对应的值,可以读取、修改
  • 添加键值对可以直接通过 d[key] = value 来进行
  • 删除键值对可以直接 del d[key]
  • 通过 d[key] 访问值时如果不存在 key 这个键会抛出异常
    • 通过 d.get(key) 来访问值时如果不存在则会返回 None
    • 使用 d.get(key, default) 如果没有 key 时会返回 default 值
  • d.update(d2) 来用 d2 中的键值对更新 d

布尔表达式


  • == 判断相等(相等则返回 True),!= 判断不等
  • 使用 and or not 来进行布尔运算,必要时加括号保证优先级
  • 数值比较大小 < <= > >=
  • 判断元素是否在列表中
    • value in lst:如果在则值为 True
    • value not in lst:如果在则为 False(判断是否不在)
  • 判断键是否在字典中
    • key in d、key not in d 与列表同理

条件语句


  • if-elif-else 结构(不是 else if)
  • elif、else 均可以省略
  • 条件不需要加括号(加了也没问题)
  • condition 会被转换成 bool 类型然后判断
  • 注意缩进
  • 类三目运算符写法 a if condition else b
    • 类似其它语言中的 condition? a : b
if condition1:
  3 |     ...
  4 | elif condition2:
  5 |     ...
  6 | elif condition3:
  7 |     ...
  8 | else:
  9 |     ...
 10 | 

缩进


  • 缩进是 python 中很重要的东西,python 靠缩进来得到代码结构,而不是大括号
  • 缩进可以使用空格或制表符
  • 如果一些代码处于同一层缩进下,则属于同一个代码块
  • 同一个代码块的缩进要统一
    • 不仅仅是看着像,要区分好空格与制表符
    • 4 个空格与一个显示宽度为 4 的制表符并不是同一缩进
  • 一般使用 4 空格缩进,或者 1 制表符缩进
  • 编辑器中按 Tab 打出的也不一定是制表符,要分清
  • 缩进不正确会报 IndentationError,此时注意检查缩进

for 循环


  • python 中的 for 循环并不像 c 中是指定一个变量的变化方式,而是从列表/元组/迭代器等可迭代对象中遍历值
  • for 循环会产生一个用于循环的变量,这个变量在循环结束后并不会删除,而是保留最后一次的值
  • 可以使用 range 来生成一串数字用来循环
    • range(a, b) 生成从 a 到 b-1 的连续整数
    • range(a, b, c) 以 c 为步长生成
    • range 得到的并不是列表,如果要用其生成列表要使用 list(range(...))
for value in lst:
 11 |     ...
 12 | 
 13 | for value in range(...):
 14 |     ...
 15 | 

for 循环遍历字典


  • 有三种方法来遍历字典
  • 在 d.keys() 中循环遍历所有键
  • 在 d.values() 中循环遍历所有值
  • 在 d.items() 中遍历键值对(需要解包)
for key in d.keys():
 16 |     ...
 17 | 
 18 | for value in d.values():
 19 |     ...
 20 | 
 21 | for item in d.items():
 22 |     ... # item 为一个元组
 23 | 
 24 | for key, value in d.items():
 25 |     ... # 将 item 解包
 26 | 

元素解包


  • 赋值时等号左侧可以是用逗号分隔的多个值,这时会将右侧解包分别赋值给左侧的各个变量
  • 右侧也可以是多个值(只要出现逗号就会视为一个元组)
    • 可以通过 a, b = b, a 实现元素交换
  • 星号表达式
    • 可以用来在可迭代对象内部解包
    • 也可用来标记一个变量包含多个值
  • for 循环可以解包
t = (1, 2, 3)
 27 | a, b, c = t # a = 1, b = 2, c = 3
 28 | t = (1, 2, (3, 4))
 29 | a, b, (c, d) = t # c = 3, d = 4
 30 | 
 31 | l = [1, 2, *[3, 4]] # [3, 4] 被解包
 32 | # l = [1, 2, 3, 4]
 33 | a, *b = [1, 2, 3, 4]
 34 | # a = 1, b = [2, 3, 4]
 35 | 
 36 | lst = [[1, 2], [3, 4]]
 37 | for a, b in lst:
 38 |     ... # 第一次循环 a, b 为 1, 2
 39 |         # 第二次循环 a, b 为 3, 4
 40 | 

for 循环技巧


  • enumerate 计数
    • 可以指定初始值
  • zip 同时循环多个可迭代对象
    • 循环次数为最短的对象的长度
for i, value in enumerate(lst):
 41 |     ... # i 依次为 0,1,2,……
 42 | 
 43 | for i, value in enumerate(lst, 1):
 44 |     ... # i 依次为 1,2,3,……
 45 | 
 46 | for a, b in zip(lst1, lst2):
 47 |     ... # a 在 lst1 中循环
 48 |         # b 在 lst2 中循环
 49 | 

列表推导


  • 一种很方便的生成列表的方式
  • 即在列表中包含循环,逐次记录循环前表达式的值
  • 可以有多重循环,即生成笛卡尔积
  • 可以包含条件,即在条件成立时才记录值
  • 列表推导中的循环变量有局部作用域
    • 即在列表推导外不能访问循环变量
lst = []
 50 | for i in range(1, 10):
 51 |     lst.append(i**2)
 52 | # 等价于
 53 | lst = [i**2 for i in range(1, 10)]
 54 | 
 55 | lst1 = [x*y for x in l1 for y in l2]
 56 | 
 57 | lst2 = [... for ... in ... if ...]
 58 | 

生成元组/字典


  • 可以使用和列表推导类似的方法生成元组和字典
  • 生成元组的时候要用 tuple()
    • 只写 () 的话则只是生成器表达式
  • 生成字典时循环前用 : 将键值隔开
tuple(i**2 for i in range(1, 10))
 59 | 
 60 | (i**2 for i in range(1, 10))
 61 | # ^  generator object
 62 | 
 63 | {a: b for a in ... for b in ... }
 64 | 

控制循环


  • 和其它语言一样,在循环代码块中可以控制循环的进行
  • break 立刻结束循环
  • continue 立刻进行下一轮循环

while 循环


  • while 循环即进行条件检查,如果为 True 则继续运行直到条件不满足停止
while condition:
 65 |     ...
 66 | 

函数定义


  • 使用 def 关键字来定义函数
  • 先函数名,然后括号列出参数,下面接代码块
  • 使用 return 返回
    • 没有 return 运行到结尾,返回 None
    • 只有 return,返回 None
    • return 后接内容,返回内容
    • return 的值类型不要求一致
    • return 可以返回多个值(利用元组)
def func_name(arg1, arg2):
 67 |     ...
 68 | 
 69 | def func_name(arg1, arg2):
 70 |     ...
 71 |     return ...
 72 | 
 73 | def func_name(arg1, arg2):
 74 |     ...
 75 |     return ..., ...
 76 | 

函数参数


  • 括号中要列出参数名,供函数体内使用
  • 可以在参数后接等号赋默认值
    • 使用默认值的参数在调用时可以不用传
  • 利用 * 来接收任意多参数
    • 接收进来是一个元组
    • * 参数后面不能再有其它非关键字参数
  • 利用 ** 来接收任意多关键字参数
    • 接收进来是一个字典
def func(arg1, arg2):
 77 |     ...
 78 | 
 79 | def func(arg1, arg2="..."): # 默认值
 80 |     ...
 81 | 
 82 | def func(arg1, *arg2): # 任意多参数
 83 |     ...
 84 | 
 85 | def func(arg1, **arg2): # 任意多关键字参数
 86 |     ...
 87 | 
 88 | def func(arg1, *arg2, **arg3):
 89 |     ... # *arg2 后可以加 **arg3
 90 | 

函数调用


  • 通过 函数名(参数) 来调用函数,得到返回值
  • 直接传参的话要将参数与定义对应上
  • 通过关键字传参(参数名)可以打乱顺序
  • 带有默认值的参数如果不传则使用默认值
  • 如果读任意多关键字参数,则多余的读到字典中
def func(a, b):
 91 |     ...
 92 | 
 93 | func(1, 2) # a = 1, b = 2
 94 | func(b=1, a=2) # a = 2, b = 1
 95 | 
 96 | def func2(a, **b):
 97 |     ...
 98 | 
 99 | func2(a=1, b=2, c=3)
100 | # a = 1, b = {"b": 2, "c": 3}
101 | 

引用变量


  • python 中的变量都是引用的(这也就是为什么前面说不要将变量理解为盒子)
  • 用 = 实际上是定义了一个别名
    • lst1 = lst2,则 lst1 和 lst2 会同时变化(要用 [:] 创建副本)
    • 数值类型有优化,所以不会这样
    • == 检查值是否相等,is 检查值是否相同
    • 观察 pythontutor.com
  • 函数参数传递只有“共享传参”一种形式(即传引用)
    • 可变变量(例如列表)在函数内部可以被改变
    • 避免向函数传递可变变量(列表可传入 [:] 创建的副本)

匿名函数


  • 可以通过 lambda 表达式来定义匿名函数
  • lambda 输入: 输出表达式
  • 可以有多个输入
  • 可以将一个函数赋值给一个变量
  • 避免用 lambda 赋值的形式定义函数
    • 例如 __name__ 属性不会是函数名,而是 "<lambda>"
lambda a: a**2 + 2*a + 1
102 | (lambda a: a**2 + 2*a + 1)(2) # 9
103 | 
104 | lambda a, b: a*2 + b
105 | 
106 | f = lambda a: a**2 + 2*a + 1
107 | # 近似等价于
108 | def f(a):
109 |     return a**2 + 2*a + 1
110 | 

用户输入


  • 读取用户输入使用内置的 input 函数
  • 函数参数为要显示的提示符,例如 input("> ")
  • 函数的返回值为一个字符串
  • 每次读入一行(即读到换行为止)

高阶函数用法


  • 接收函数作为参数的函数被称为高阶函数
  • 比较常用的有 map、filter
list(map(lambda x: x*2, [1, 2]))
111 | # [2, 4]
112 | list(filter(lambda x: x>1, [1, 2, 3]))
113 | # [2, 3]
114 | 


  • 类可以看成包含一些属性方法的框架
  • 根据类来创建对象 -> 实例化
  • 用 class 关键字来定义类
  • 类中的函数 -> 方法
    • 特殊方法 __init__,在类实例化的时候会被自动调用
    • 其它一般的方法第一个参数都要为"self",调用的时候会自动传入
  • 直接写在类中的是属性,也可以通过为 self.<name> 赋值的形式创建属性
  • 用类似函数调用的形式实例化类,参数为__init__方法的参数
  • 直接通过 .<method> .<attribute> 的形式调用方法/获取属性
class ClassName():
115 |     a = 1
116 |     def __init__(self, arg1, arg2):
117 |         self.arg1 = arg1
118 |         self.arg2 = arg2
119 |     def method(self):
120 |         print(self.arg1, self.arg2, self.a)
121 | 
122 | obj = ClassName(2, 3)
123 | obj.method() # 2 3 1
124 | print(obj.a, obj.arg1) # 1 2
125 | 

类的继承


  • 在 class 定义的括号中加上另一个类名则表示继承自那个类定义一个子类
  • 子类会继承父类的所有属性和方法
  • 子类编写和父类名字一样的方法会重载
  • 在重载的方法中调用父类的原方法使用 super()
  • 也可以为子类定义独有的方法
class ClassA():
126 |     def __init__(self, a):
127 |         self.a = a
128 |     def print(self):
129 |         print(self.a)
130 | 
131 | class ClassB(ClassA):
132 |     def __init__(self, a):
133 |         super().__init__(a)
134 |         self.a *= 2
135 | 
136 | obj = ClassB(1)
137 | obj.print() # 2
138 | 

私有?


  • python 中类并没有严格私有的属性
  • 双下划线开头的属性会被隐藏,不能直接读取
  • 但这种属性可以通过 _类名__属性 但方式读取到
  • 使用双下划线开头的属性可以轻微保护属性,但并不代表其是私有的
class A():
139 |     a = 1
140 |     _a = 2
141 |     __a = 3
142 | 
143 | obj = A()
144 | print(obj.a) # 1
145 | print(obj._a) # 2
146 | print(obj.__a) # AttributeError
147 | print(obj._A__a) # 3
148 | 

一切皆对象?


  • python 中即使最简单的整数也是一个类的实例
  • 通过 dir(...) 查看一个对象的所有属性/方法
  • 有很多双下划线开头、双下划线结尾的方法,成为魔术方法(dunder method)

魔术方法


  • 很多函数、表达式其实是通过调用类的魔术方法来实现的
  • len(obj) 调用 obj.__len__()
  • obj[...] 调用 obj.__getitem__(...)
  • a in obj 调用 obj.__contains__(a)
  • bool(obj) 调用 obj.__bool__()
  • 函数的调用本质上是调用 func.__call__()
  • a + b 调用 a.__add__(b)
  • ......

一个例子:

  • lst[a:b:c] 切片操作
  • 其中切片也是一个对象,它是一个 slice 类的实例
    • 所以它等价于 lst[slice(a, b, c)]
  • 而通过 [] 的操作又是通过 __getitem__ 魔术方法实现的
    • 所以它又等价于 lst.__getitem__(slice(a, b, c))
  • __getitem__ 方法中处理了 slice,读取 abc 的值,再处理返回一个新列表

就这?


  • python 中类还有更多更多更好玩的用法
  • 静态方法、类方法……
  • 多重继承、mro 顺序……
  • 接口协议、鸭子类型、抽象基类……
  • 猴子补丁……
  • 元类……
  • 垃圾回收……
  • .......

文件操作


  • open 函数,传入文件名、打开模式
  • 打开模式(可以叠加):r 读(默认)、w 写、x 创建并写、a 写在末尾、b 字节模式、t 文本模式(默认)
  • 读取
    • 文本模式建议加上 encoding,不然容易报错
    • f.read() 读取全部内容(字节模式得到字节序列)
    • f.readline() 读取一行
    • f.readlines() 读取所有行,返回一个列表
  • 写入
    • 文本模式同样建议加上 encoding
    • f.write(...) 直接写入
    • f.writelines(...) 传入列表,元素间换行写入
  • 通过这种形式操作文件记得用完后要 f.close()
f = open("filename", "r", encoding="utf-8")
149 | s = f.read()            # a str
150 | # line = f.readline()   # a str
151 | # lines = f.readlines() # a list
152 | ...
153 | f.close()
154 | 
155 | f = open("filename", "w", encodeing="utf-8")
156 | f.write("...")
157 | f.writelines(["...", "..."])
158 | ...
159 | f.close()
160 | 

with 块


  • with ... as ...: 开启一个上下文管理器
  • 常用在文件 open 上
    • with 块开始自动打开
    • with 块结束自动结束
  • with 块结束后变量仍会留存
with open("file", "r", encoding="utf-8") as f:
161 |     s = f.read()
162 |     ...
163 | 
164 | print(f.closed)  # True
165 | 

异常与处理


  • 产生错误 -> 抛出异常 -> 程序结束
  • raise 关键字抛出异常
  • try-except 块捕获异常
    • 可以有多个 except、不可以没有
    • except 后接异常类(没有则捕获所有)
    • as 字句存下异常
  • finally 语句
    • 不管是否有异常都会运行
raise ...
166 | raise RuntimeError("...")
167 | 
168 | try:
169 |     input(">>> ")
170 | except KeyboardInterrupt:
171 |     print("Good bye")
172 | 
173 | try:
174 |     print(1 / 0)
175 | except ZeroDivisionError as e:
176 |     print("can't devide by zero")
177 |     raise e
178 | finally:
179 |     print("finished")
180 | 

if 外的 else 语句


  • else 块不仅仅跟着 if 才能使用
  • for-else
    • for 循环结束才会运行
    • for 循环被 break 了不会运行
  • while-else
    • condition 不成立退出才会运行
    • 循环被 break 终止了不会运行
  • try-else
    • try 块中没有异常出现才会运行
    • else 块中异常不会被前面的 except 捕获
  • 程序流跳到块外了不会运行(return 等)
for value in lst:
181 |     ...
182 | else:
183 |     ...
184 | 
185 | while condition:
186 |     ...
187 | else:
188 |     ...
189 | 
190 | try:
191 |     ...
192 | except ...:
193 |     ...
194 | else:
195 |     ...
196 | 

模块与导入


  • 模块可以是一个单独的 .py 文件,也可以是一个文件夹
    • 文件夹相当于导入其下 __init__.py 文件
  • 模块中正常编写函数、类、语句
  • 通过 import 语句导入模块
    • import code
    • import code as cd
    • from code import ...
    • from code import *
  • 导入时相当于运行了一遍导入的代码
# code.py
197 | print("hello")
198 | def f():
199 |     print("call func in code.py")
200 | ...
201 | 
import code # hello
202 | code.f()
203 | import code as cd # hello
204 | cd.f()
205 | from code import f # hello
206 | f()
207 | from code import * # hello
208 | f()
209 | 

”main 函数“


  • 防止导入时运行代码
  • 只允许直接运行脚本时运行
  • 通过判断 __name__
    • 如果是直接运行,则其等于字符串 __main__
    • 如果是被导入的,则其等于模块名
# code.py
210 | ...
211 | if __name__ == "__main__":
212 |     print("hello")
213 | else:
214 |     print(__name__)
215 | 
import code # code
216 | 
$ python code.py # hello
217 | 

内部模块


  • python 自带了很多实用的模块(标准库)
  • os、sys:系统操作
  • math:数学运算
  • re:正则表达式
  • datetime:日期与时间
  • subprocess:子进程管理
  • argparse:命令行参数解析
  • logging:日志记录
  • hashlib:哈希计算
  • random:随机数
  • csv、json:数据格式解析
  • collections:更多类型
  • ...

外部模块安装


  • pypi.org 上有极多别人写好了可以用的模块
    • numpy 矩阵等科学计算、scipy 科学计算、matplotlib 作图……
  • 使用 pip 安装(pip / python -m pip)
    • pip install pkg_name
    • pip install pkg_name=... 指定版本
    • pip install -r requirements.txt 安装 txt 文件中的所有包
    • pip install ... -i https://pypi.tuna.tsinghua.edu.cn/simple 换源
    • pip list、pip show 命令查看安装的所有包/某个包的信息
    • pip uninstall pkg_name 卸载包
  • pip 安装本地模块
    • 目录下需要包含 setup.py / pyproject.toml
    • pip install . 安装本地模块(复制到 site-packages 中)
    • pip install -e . 可修改形式安装本地模块(在当前位置,可以直接修改代码)

文档字符串


  • 模块开头的三引号字符串
  • 类、函数定义下面的三引号字符串
  • help(...) 的时候可以显示
  • obj.__doc__ 表示这串字符串
  • 编辑器用来提示
  • 一些文档生成工具(sphinx 等)从中获取文档
"""
218 | docstring for module
219 | """
220 | 
221 | def func(...):
222 |     """docstring for function"""
223 |     ...
224 | 
225 | class A():
226 |     """docstring for class"""
227 |     def __init__(self, ...):
228 |         """docstring for method"""
229 |         ...
230 | 

代码规范


更多?



Thanks for watching

-------------------------------------------------------------------------------- /docs/js/chunk-vendors.js: -------------------------------------------------------------------------------- 1 | /*! For license information please see chunk-vendors.js.LICENSE.txt */ 2 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-vendors"],{"0104":function(e,t,s){"use strict";s.r(t);const i=window.CustomEvent;var n=function(){try{const e=new i("t",{detail:{a:"b"}});return"t"===e.type&&"b"===e.detail.a}catch(e){}return!1}()?i:function(e,t){const s=document.createEvent("CustomEvent");return t?s.initCustomEvent(e,t.bubbles,t.cancelable,t.detail):s.initCustomEvent(e,!1,!1,void 0),s};let o="",l="";class a{static createNode(e,t="",s=""){const i=document.createElement(e);return t&&(i.id=t),s&&(i.textContent=s),i}static once(e,t,s){const i=n=>{n.target===e&&(e.removeEventListener(t,i),s(n))};e.addEventListener(t,i,!1)}static getTransitionEvent(e){if(o&&!e)return o;o="";const t=e||document.createElement("ws"),s={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"},i=Object.keys(s);for(let e=0,n=i.length;e-1||t}return e}static parseSize(e){return Number(e.replace(/[^\d\.]/g,""))}static wrap(e,t){const s=document.createElement(t);return e.parentElement.insertBefore(s,e),s.appendChild(e),s}static after(e,t){const s=t.parentNode;s.lastChild===t?s.appendChild(e):s.insertBefore(e,t.nextSibling)}}const r=["INPUT","SELECT","OPTION","BUTTON","A","TEXTAREA"];var d={ENTER:13,SPACE:32,RE_PAGE:33,AV_PAGE:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PLUS:[107,171,187],MINUS:[109,173,189],ESCAPE:27,F:70};const h=/#slide=(\d+)/;class c{constructor(e){this.ws_=e,e.el.addEventListener("ws:slide-change",c.onSlideChange_),window.addEventListener("hashchange",this.onHashChange_.bind(this),!1)}onHashChange_(){const e=c.getSlideNumber();null!==e&&this.ws_.goToSlide(e)}static onSlideChange_(e){c.setSlideNumber(e.detail.currentSlide)}static getSlideNumber(){const e=document.location.hash.match(h);let t=0;return Array.isArray(e)&&(t=parseInt(e[1],10)),"number"!=typeof t||t<0||!Array.isArray(e)?t=null:t--,t}static setSlideNumber(e){c.getSlideNumber()!==e-1&&history.pushState({slideI:e-1},"Slide "+e,"#slide="+e)}}const u="next",_="previous",m="counter",w={VERTICAL:{NEXT:"↓",PREV:"↑"},HORIZONTAL:{NEXT:"→",PREV:"←"}};class p{constructor(e){const t=e.isVertical?w.VERTICAL:w.HORIZONTAL;this.el=a.createNode("div","navigation"),this.next=p.createArrow(u,t.NEXT),this.prev=p.createArrow(_,t.PREV),this.counter=p.createCounter(m,e),this.ws_=e,this.el.appendChild(this.next),this.el.appendChild(this.prev),this.el.appendChild(this.counter),this.ws_.el.appendChild(this.el),this.bindEvents_()}bindEvents_(){this.ws_.el.addEventListener("ws:slide-change",this.onSlideChanged_.bind(this)),this.next.addEventListener("click",this.onButtonClicked_.bind(this)),this.prev.addEventListener("click",this.onButtonClicked_.bind(this)),this.counter.addEventListener("click",this.onButtonClicked_.bind(this))}updateCounter(e,t){this.ws_.options.showIndex?this.counter.childNodes[0].textContent=`${e} / ${t}`:this.counter.textContent=`${e} / ${t}`}static createArrow(e,t){const s=a.createNode("a",e,t);return s.href="#",s.title="Arrow Keys",s}static createCounter(e,t){const s=a.createNode("span",e);if(t.options.showIndex){const e=document.createElement("a");e.href="#",e.title="View all slides",s.appendChild(e)}return s}onSlideChanged_(e){this.updateCounter(e.detail.currentSlide,e.detail.slides)}onButtonClicked_(e){e.preventDefault(),e.target===this.next?this.ws_.goNext():e.target===this.prev?this.ws_.goPrev():this.ws_.toggleZoom()}}const g=window.navigator.userAgent;class b{static isAndroid(){return!!g.match(/Android/i)}static isBlackBerry(){return!!g.match(/BlackBerry/i)}static isiOS(){return!!g.match(/iPad|iPhone|iPod/i)}static isOpera(){return!!g.match(/Opera Mini/i)}static isWindows(){return!!g.match(/IEMobile/i)}static isWindowsPhone(){return!!g.match(/Windows Phone/i)}static isAny(){return b.isAndroid()||b.isBlackBerry()||b.isiOS()||b.isOpera()||b.isWindows()||b.isWindowsPhone()}}const v={START:"touchstart",MOVE:"touchmove",END:"touchend"},y={START:"pointerdown",MOVE:"pointermove",END:"pointerup"};class E{constructor(e){let t;this.ws_=e,this.startX_=0,this.startY_=0,this.endX_=0,this.endY_=0,this.isEnabled=!1,this.isGesture=!1,this.startTouches=[],this.endTouches=[],b.isAny()&&(t=window.PointerEvent&&(b.isWindows()||b.isWindowsPhone())?y:v,this.isEnabled=!0,document.addEventListener(t.START,this.onStart_.bind(this),!1),document.addEventListener(t.MOVE,this.onMove_.bind(this),!1),document.addEventListener(t.END,this.onStop_.bind(this),!1))}onStart_(e){if(this.ws_.isDisabled())return;const t=E.normalizeEventInfo(e);1===e.touches.length?(this.startX_=t.x,this.startY_=t.y,this.endX_=t.x,this.endY_=t.y):e.touches.length>1&&(this.startTouches=E.getTouchCoordinates(e),this.endTouches=this.startTouches,this.isGesture=!0)}onMove_(e){if(this.ws_.isDisabled())return;const t=E.normalizeEventInfo(e);this.isGesture?this.endTouches=E.getTouchCoordinates(e):(this.endX_=t.x,this.endY_=t.y)}onStop_(){if(!this.ws_.isDisabled())if(this.isGesture){Math.sqrt(Math.pow(this.startTouches[0].x-this.startTouches[1].x,2)+Math.pow(this.startTouches[0].y-this.startTouches[1].y,2))>Math.sqrt(Math.pow(this.endTouches[0].x-this.endTouches[1].x,2)+Math.pow(this.endTouches[0].y-this.endTouches[1].y,2))&&this.ws_.toggleZoom(),this.isGesture=!1}else{const e=this.startX_-this.endX_,t=this.startY_-this.endY_;Math.abs(e)>Math.abs(t)&&(e<-this.ws_.options.slideOffset?this.ws_.goPrev():e>this.ws_.options.slideOffset&&this.ws_.goNext())}}static getTouchCoordinates(e){return[{x:e.touches[0].clientX,y:e.touches[0].clientY},{x:e.touches[1].clientX,y:e.touches[1].clientY}]}static normalizeEventInfo(e){let t={pageX:0,pageY:0};void 0!==e.changedTouches?t=e.changedTouches[0]:void 0!==e.originalEvent&&void 0!==e.originalEvent.changedTouches&&(t=e.originalEvent.changedTouches[0]);return{x:e.offsetX||e.layerX||t.pageX,y:e.offsetY||e.layerY||t.pageY}}}const S="slide",f="current",A="dom:enter",T="dom:leave",N="slide:enable",L="slide:disable";class C{constructor(e,t){this.el=e,this.parent=e.parentNode,this.i=t,this.el.id="section-"+(t+1),this.el.classList.add(S),this.hide()}hide(){a.hide(this.el),this.el.classList.remove(f)}show(){a.show(this.el),this.el.classList.add(f)}moveAfterLast(){const e=this.parent.childNodes[this.parent.childElementCount-1];this.fire_(T),this.parent.insertBefore(this.el,e.nextSibling),this.fire_(A)}moveBeforeFirst(){const e=this.parent.childNodes[0];this.fire_(T),this.parent.insertBefore(this.el,e),this.fire_(A)}enable(){this.fire_(N)}disable(){this.fire_(L)}fire_(e){a.fireEvent(this.el,e,{slide:this})}static isCandidate(e){return 1===e.nodeType&&"SECTION"===e.tagName}static getSectionFromEl(e){let t=e,s=null,i=null;for(;t.parentElement&&!t.classList.contains(S);)t=t.parentElement;return t.classList.contains(S)&&(s=t,i=parseInt(s.id.replace("section-",""),10)),{section:s,i:i}}}class k{constructor(e){this.ws_=e;const t=a.toArray(this.ws_.el.querySelectorAll("video"));t.length&&t.forEach(t=>{if(!t.hasAttribute("autoplay"))return;t.removeAttribute("autoplay"),t.pause(),t.currentTime=0;const{i:s}=C.getSectionFromEl(t),i=e.slides[s-1];i.video=t,i.el.addEventListener(N,k.onSectionEnabled),i.el.addEventListener(L,k.onSectionDisabled)})}static onSectionEnabled(e){e.detail.slide.video.play()}static onSectionDisabled(e){e.detail.slide.video.pause()}}class P{constructor(e){this.ready=!1,this.onReadyCb=null,this.slide=C.getSectionFromEl(e).section,this.autoplay=void 0!==e.dataset.autoplay,this.isMuted=void 0!==e.dataset.mute,this.options={videoId:e.dataset.youtubeId,playerVars:this.getPlayerVars(e),events:{onReady:this.onPlayerReady.bind(this)}},this.el=e,this.timeout=null,this.create()}destroy(){this.currentTime=this.player.getCurrentTime(),this.player.destroy(),this.player=null,this.el=this.slide.querySelector("[data-youtube]"),this.ready=!1}create(){this.player=new YT.Player(this.el,this.options),this.el=this.player.getIframe()}onPlayerReady(){this.ready=!0,this.currentTime&&(this.player.seekTo(this.currentTime,!0),this.player.pauseVideo(),this.currentTime=null),this.timeout&&1!==this.player.getPlayerState()&&this.play(),this.onReadyCb&&(this.onReadyCb(),this.onReadyCb=null)}play(){this.ready?(this.timeout=setTimeout(()=>{this.timeout=null},1e3),this.isMuted?this.player.mute():this.player.unMute(),this.player.playVideo()):this.onReadyCb=this.play}pause(){this.player&&this.player.pauseVideo&&1===this.player.getPlayerState()&&this.player.pauseVideo()}getPlayerVars(e){const t={modestbranding:1,rel:0,origin:window.location.origin};return this.slide.classList.contains("fullscreen")&&(t.disablekb=1),void 0!==e.dataset.noControls&&(t.controls=0,t.showinfo=0),void 0!==e.dataset.loop&&(t.loop=1,t.playlist=e.dataset.youtubeId),t}}class x{constructor(e){this.ws_=e,this.videos=a.toArray(this.ws_.el.querySelectorAll("[data-youtube]")),this.videos.length&&this.inject()}onYTReady(){this.videos.forEach(e=>{const t=new P(e);if(void 0!==e.dataset.autoplay){const{i:e}=C.getSectionFromEl(t.el),s=this.ws_.slides[e-1];s.player=t,s.el.addEventListener(N,x.onSlideEvent),s.el.addEventListener(L,x.onSlideEvent),s.el.addEventListener(A,x.onSlideEvent),s.el.addEventListener(T,x.onSlideEvent),this.ws_.currentSlide_===s&&x.onSectionEnabled(s)}})}inject(){window.onYouTubeIframeAPIReady=this.onYTReady.bind(this);const e=document.createElement("script");e.src="https://www.youtube.com/iframe_api";const t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}static onSlideEvent(e){const t=e.detail.slide;switch(e.type){case N:x.onSectionEnabled(t);break;case L:x.onSectionDisabled(t);break;case T:t.player.destroy();break;case A:t.player.create()}}static onSectionEnabled(e){e.player.autoplay&&e.player.play()}static onSectionDisabled(e){e.player.pause()}}var I={swing:function(e){return.5-Math.cos(e*Math.PI)/2}};let O=document.getElementById("webslides");function z(e,t=500,s=(()=>{}),i=null){O=i||document.getElementById("webslides");const n=e-O.scrollTop,o=O.scrollTop;if(!t)return O.scrollTop=e,void s();const l=i=>{i+=16;const a=Math.min(1,i/t),r=I.swing(a,i*a,e,n,t);O.scrollTop=Math.floor(o+r*n),il(i),16):s()};l(0)}const M="grid",V="column",D="wrap-zoom",R="wrap",B="current",F="ws-ready-zoom";var K={AutoSlide:class{constructor(e){this.ws_=e,this.interval_=null,this.time=this.ws_.options.autoslide,this.time&&(a.once(e.el,"ws:init",this.play.bind(this)),document.body.addEventListener("focus",this.onFocus.bind(this)))}onFocus(){a.isFocusableElement()?this.stop():null===this.interval_&&this.play()}play(e){"number"!=typeof e&&(e=this.time),this.time=e,!this.interval_&&"number"==typeof e&&e>0&&(this.interval_=setInterval(this.ws_.goNext.bind(this.ws_),e))}stop(){this.interval_&&(clearInterval(this.interval_),this.interval_=null)}},ClickNav:class{constructor(e){this.ws_=e,e.options.changeOnClick&&this.ws_.el.addEventListener("click",this.onClick_.bind(this))}onClick_(e){r.indexOf(e.target.tagName)<0&&void 0===e.target.dataset.preventNav&&this.ws_.goNext()}},Grid:class{constructor(e){this.ws_=e;const t="body.baseline {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAACVBMVEUAAAAtXsUtXcPDDPUWAAAAA3RSTlMAZmHzZFkxAAAAFklEQVQI12MAA9bBR3ExhAJB1iooBQBGwgVEs/QtuAAAAABJRU5ErkJggg==) left top .8rem/.8rem;\n }",s=document.head||document.getElementsByTagName("head")[0],i=document.createElement("style");i.type="text/css",i.styleSheet?i.styleSheet.cssText=t:i.appendChild(document.createTextNode(t)),s.appendChild(i),document.addEventListener("keydown",this.onKeyPress_.bind(this),!1)}onKeyPress_(e){e.which===d.ENTER&&document.body.classList.toggle("baseline")}},Hash:c,Keyboard:class{constructor(e){this.ws_=e,document.addEventListener("keydown",this.onKeyPress_.bind(this),!1)}onKeyPress_(e){let t,s;if(!a.isFocusableElement()&&!this.ws_.isDisabled()){switch(e.which){case d.AV_PAGE:t=this.ws_.goNext;break;case d.SPACE:t=e.shiftKey?this.ws_.goPrev:this.ws_.goNext;break;case d.RE_PAGE:t=this.ws_.goPrev;break;case d.HOME:t=this.ws_.goToSlide,s=0;break;case d.END:t=this.ws_.goToSlide,s=this.ws_.maxSlide_-1;break;case d.DOWN:t=this.ws_.isVertical?this.ws_.goNext:null;break;case d.UP:t=this.ws_.isVertical?this.ws_.goPrev:null;break;case d.LEFT:t=this.ws_.isVertical?null:this.ws_.goPrev;break;case d.RIGHT:t=this.ws_.isVertical?null:this.ws_.goNext;break;case d.F:e.metaKey||e.ctrlKey||(t=this.ws_.fullscreen)}t&&(t.call(this.ws_,s),e.preventDefault())}}},Navigation:p,Scroll:class{constructor(e){this.ws_=e,this.scrollContainer_=e.el,this.isGoingUp_=!1,this.isGoingLeft_=!1,this.timeout_=null,this.ws_.options.navigateOnScroll&&(b.isAny()||(this.scrollContainer_.addEventListener("wheel",this.onMouseWheel_.bind(this)),e.isVertical||e.el.addEventListener("ws:slide-change",this.onSlideChange_.bind(this))))}onSlideChange_(){this.timeout_=setTimeout(()=>{this.timeout_=null},this.ws_.options.scrollWait)}onMouseWheel_(e){if(this.ws_.isDisabled())return;if(this.ws_.isMoving||this.timeout_)return void e.preventDefault();const t=e.deltaMode*this.ws_.options.minWheelDelta,{deltaY:s,deltaX:i}=e,n=this.ws_.isVertical,o=Math.abs(i)>Math.abs(s);if(this.isGoingUp_=s<0,this.isGoingLeft_=i<0,o){if(n)return;e.preventDefault()}(Math.abs(s+t)>=this.ws_.options.minWheelDelta||Math.abs(i+t)>=this.ws_.options.minWheelDelta)&&(o&&this.isGoingLeft_||!o&&this.isGoingUp_?this.ws_.goPrev():this.ws_.goNext(),e.preventDefault())}},Touch:E,Video:k,YouTube:x,Zoom:class{constructor(e){this.ws_=e,this.zws_={},this.isZoomed_=!1,this.preBuildZoom_(),document.body.addEventListener("keydown",this.onKeyDown.bind(this))}onKeyDown(e){!this.isZoomed_&&d.MINUS.some(t=>t===e.which)?this.zoomIn():this.isZoomed_&&(d.PLUS.some(t=>t===e.which)||e.which===d.ESCAPE)&&this.zoomOut()}preBuildZoom_(){this.zws_.el=this.ws_.el.cloneNode(),this.zws_.el.id="webslides-zoomed",this.zws_.wrap=a.createNode("div"),this.zws_.wrap.className=R,this.zws_.el.appendChild(this.zws_.wrap),this.zws_.grid=a.createNode("div"),this.zws_.grid.className=M,this.zws_.wrap.appendChild(this.zws_.grid),this.zws_.el.addEventListener("click",()=>this.toggleZoom()),this.zws_.slides=[].map.call(this.ws_.slides,(e,t)=>{const s=e.el.cloneNode(!0);return this.zws_.grid.appendChild(s),new C(s,t)}),this.disable(),a.after(this.zws_.el,this.ws_.el),this.zws_.slides.forEach(e=>this.createSlideBlock_(e))}createSlideBlock_(e){const t=a.wrap(e.el,"div");t.className=D,t.setAttribute("id","zoomed-"+e.el.getAttribute("id"));const s=a.wrap(t,"div");s.className=V;const i=a.createNode("div");i.className="zoom-layer",i.addEventListener("click",t=>{t.stopPropagation(),this.zoomOut(),this.ws_.goToSlide(e.i)}),t.appendChild(i);const n=a.createNode("p","",""+(e.i+1));n.className="text-slide-number",s.appendChild(n)}toggleZoom(){this.isZoomed_?this.zoomOut():this.zoomIn()}zoomIn(){if(!this.ws_.options.showIndex)return;this.enable();const e=this.ws_.currentSlide_.el.id,t=this.zws_.el.querySelector(`.${D}.${B}`);t&&t.classList.remove(B);const s=this.zws_.el.querySelector("#zoomed-"+e);s.classList.add(B),this.isZoomed_=!0,document.documentElement.classList.add(F),setTimeout(()=>{this.ws_.disable(),this.zws_.el.classList.add("in");const e=window.getComputedStyle(this.zws_.grid),t=document.body;z(s.parentNode.offsetTop+a.parseSize(e.paddingTop),50,()=>{},t)},50)}zoomOut(){this.ws_.options.showIndex&&(this.zws_.el.classList.remove("in"),setTimeout(()=>{this.ws_.enable(),this.disable(),this.isZoomed_=!1,document.documentElement.classList.remove(F)},400))}disable(){this.zws_.el.classList.add("disabled")}enable(){this.zws_.el.classList.remove("disabled")}}};const W="vertical",G="ws-ready",q="disabled",X={autoslide:K.AutoSlide,clickNav:K.ClickNav,grid:K.Grid,hash:K.Hash,keyboard:K.Keyboard,nav:K.Navigation,scroll:K.Scroll,touch:K.Touch,video:K.Video,youtube:K.YouTube,zoom:K.Zoom};class Y{constructor({autoslide:e=!1,changeOnClick:t=!1,loop:s=!0,minWheelDelta:i=40,navigateOnScroll:n=!0,scrollWait:o=450,slideOffset:l=50,showIndex:a=!0}={}){if(this.el=document.getElementById("webslides"),!this.el)throw new Error("Couldn't find the webslides container!");this.isMoving=!1,this.slides=null,this.currentSlideI_=-1,this.currentSlide_=null,this.maxSlide_=0,this.isVertical=this.el.classList.contains(W),this.plugins={},this.options={autoslide:e,changeOnClick:t,loop:s,minWheelDelta:i,navigateOnScroll:n,scrollWait:o,slideOffset:l,showIndex:a},this.initialised=!1,this.removeChildren_(),this.grabSlides_(),this.createPlugins_(),this.initSlides_(),this.onInit_()}removeChildren_(){const e=this.el.childNodes;let t=e.length;for(;t--;){const s=e[t];C.isCandidate(s)||this.el.removeChild(s)}}createPlugins_(){Object.keys(X).forEach(e=>{const t=X[e];this.plugins[e]=new t(this)})}onInit_(){this.initialised=!0,a.fireEvent(this.el,"ws:init"),document.documentElement.classList.add(G)}grabSlides_(){this.slides=a.toArray(this.el.childNodes).map((e,t)=>new C(e,t)),this.maxSlide_=this.slides.length}goToSlide(e,t=null){if(this.isValidIndexSlide_(e)&&!this.isMoving&&this.currentSlideI_!==e){this.isMoving=!0;let s=!1;null!==t?s=t:this.currentSlideI_>=0&&(s=e>this.currentSlideI_);const i=this.slides[e];null===this.currentSlide_||!this.isVertical||this.plugins.touch&&this.plugins.touch.isEnabled?this.transitionToSlide_(s,i,this.onSlideChange_):this.scrollTransitionToSlide_(s,i,this.onSlideChange_)}}scrollTransitionToSlide_(e,t,s){this.el.style.overflow="hidden",e?t.show():(t.moveBeforeFirst(),t.show(),z(this.currentSlide_.el.offsetTop,0)),z(t.el.offsetTop,500,()=>{this.currentSlide_.hide(),e&&this.currentSlide_.moveAfterLast(),this.el.style.overflow="auto",setTimeout(()=>{s.call(this,t)},150)})}transitionToSlide_(e,t,s){z(0,0);let i="slideInRight";e||(t.moveBeforeFirst(),i="slideInLeft"),this.currentSlide_&&(e&&this.currentSlide_.moveAfterLast(),this.currentSlide_.hide()),t.show(),this.initialised&&this.plugins.touch&&this.plugins.touch.isEnabled?(a.once(t.el,a.getAnimationEvent(),()=>{t.el.classList.remove(i),s.call(this,t)}),t.el.classList.add(i)):s.call(this,t)}onSlideChange_(e){this.currentSlide_&&this.currentSlide_.disable(),this.currentSlide_=e,this.currentSlideI_=e.i,this.currentSlide_.enable(),this.isMoving=!1,a.fireEvent(this.el,"ws:slide-change",{slides:this.maxSlide_,currentSlide0:this.currentSlideI_,currentSlide:this.currentSlideI_+1})}goNext(){let e=this.currentSlideI_+1;if(e>=this.maxSlide_){if(!this.options.loop)return;e=0}this.goToSlide(e,!0)}goPrev(){let e=this.currentSlideI_-1;if(e<0){if(!this.options.loop)return;e=this.maxSlide_-1}this.goToSlide(e,!1)}isValidIndexSlide_(e){return"number"==typeof e&&e>=0&&e=this.maxSlide_)&&(e=0),0!==e){let t=0;for(;t{const{i:i}=C.getSectionFromEl(t),n=e.slides[i-1];n.noteNode=t,this.isSpeakerMode_||(n.el.addEventListener(N,H.onSectionEnter),n.el.addEventListener(L,H.onSectionDisabled))})}static toggleNote(e){110!==e.which||e.metaKey||e.ctrlKey||e.shiftKey||this.classList.toggle("show")}static onSectionDisabled(e){const t=e.detail.slide;document.removeEventListener("keypress",H.toggleNote.bind(t.noteNode))}static onSectionEnter(e){const t=e.detail.slide;document.addEventListener("keypress",H.toggleNote.bind(t.noteNode))}}class ${constructor(e){this.ws_=e;const t=a.toArray(this.ws_.el.querySelectorAll(".echarts")),s=a.toArray(this.ws_.el.querySelectorAll(".echarts-data"));t.length&&t.forEach((t,i)=>{const{i:n}=C.getSectionFromEl(t),o=e.slides[n-1];o.echartsInit=!1,o.echartsNode=t,o.echartsData=s[i],o.el.addEventListener(N,$.onSectionEnter)})}static onSectionEnter(e){const t=e.detail.slide||{},{echartsNode:s,echartsInit:i,echartsData:n}=t;i||setTimeout(()=>{const e=window.pluginsOptions&&window.pluginsOptions.echarts?window.pluginsOptions.echarts.theme:void 0,i=echarts.init(s,e);try{const e=JSON.parse(n.innerHTML.trim());i.setOption(e),t.echartsInit=!0}catch(e){}},800)}}class j{constructor(e){this.ws_=e;const t=a.toArray(this.ws_.el.querySelectorAll(".lang-mermaid"));t.length&&t.forEach((t,s)=>{const{i:i}=C.getSectionFromEl(t),n=e.slides[i-1];n.mermaidInit=!1,n.mermaidNode=t,n.el.addEventListener(N,j.onSectionEnter)})}static onSectionEnter(e){const t=e.detail.slide||{},{mermaidNode:s,mermaidInit:i}=t;!i&&window.mermaid&&setTimeout(()=>{const e=window.pluginsOptions&&window.pluginsOptions.mermaid?window.pluginsOptions.mermaid.theme:void 0;mermaid.initialize({theme:e||"default"}),s.style.visibility="visible",mermaid.init(void 0,s),t.mermaidInit=!0},800)}}Y.registerPlugin("echarts",$),Y.registerPlugin("mermaid",j),Y.registerPlugin("keyboard",class{constructor(e){this.ws_=e,this.enable_=!1,this.init_(),this.bindEvent_()}bindEvent_(){this.ws_.el.addEventListener("ws:slide-change",this.slideBuild_.bind(this),!1),document.addEventListener("keydown",this.onKeyPress_.bind(this),!1),document.addEventListener("control:keydown",this.onKeyPress_.bind(this),!1)}init_(){const e=U(this.ws_.el.querySelectorAll(".build>*"));e.length&&e.forEach(e=>{e.classList.add("tobuild")})}onKeyPress_(e){let t,s;if(!a.isFocusableElement()&&!this.ws_.isDisabled()){switch(e.which){case d.AV_PAGE:t=this.enable_?this.goNext:this.ws_.goNext;break;case d.SPACE:t=e.shiftKey?this.enable_?this.goPrev:this.ws_.goPrev:this.enable_?this.goNext:this.ws_.goNext;break;case d.RE_PAGE:t=this.enable_?this.goPrev:this.ws_.goPrev;break;case d.HOME:t=this.ws_.goToSlide,s=0;break;case d.END:t=this.ws_.goToSlide,s=this.ws_.maxSlide_-1;break;case d.DOWN:t=this.ws_.isVertical?this.enable_?this.goNext:this.ws_.goNext:null;break;case d.UP:t=this.ws_.isVertical?this.enable_?this.goPrev:this.ws_.goPrev:null;break;case d.RIGHT:t=this.ws_.isVertical?null:this.enable_?this.goNext:this.ws_.goNext;break;case d.LEFT:t=this.ws_.isVertical?null:this.enable_?this.goPrev:this.ws_.goPrev;break;case d.F:e.metaKey||e.ctrlKey||(t=this.ws_.fullscreen)}t&&(t.call(this.enable_?this:this.ws_,s),e.preventDefault())}}goNext(){const e=this.curSlide_.el,t=U(e.querySelectorAll(".building"));let s;if(t.length)for(;s=t.shift();)s=s.classList,s.remove("building"),s.add("builded");const i=U(e.querySelectorAll(".tobuild"));if(!i.length)return this.enable_=!1,this.ws_.goNext(),!1;return s=i[0].classList,s.remove("tobuild"),s.add("building"),!0}goPrev(){const e=this.curSlide_.el,t=U(e.querySelectorAll(".building"));let s,i,n=t.length;if(n)for(;s=t.shift();){let e=s.classList;e.remove("building"),e.add("tobuild"),i=s}const o=U(e.querySelectorAll(".builded"));if(!o.length&&!n)return this.enable_=!1,this.ws_.goPrev(),!1;let l=o.pop();return l&&(i||(i=l),s=l.classList,s.remove("builded"),0===n?(s.add("tobuild"),l=o.pop(),l&&(l.classList.remove("builded"),l.classList.add("building"))):s.add("building")),!0}slideBuild_(e){if(e&&e.detail){const t=e.detail.currentSlide0,s=this.ws_.slides[t];this.curSlide_=s;if(U(s.el.querySelectorAll(".tobuild,.builded")).length)return void(this.enable_=!0)}this.enable_=!1}}),Y.registerPlugin("speakermode",class{constructor(e){this.ws_=e,this.init_()}bindEvent_(){window.addEventListener("message",this.evtHandler_,!1),document.addEventListener("keydown",this.onKeyPress_.bind(this),!1)}onKeyPress_(e){e.detail&&e.detail.salt||!this.listener_||this.listener_.postMessage({which:e.which,shiftKey:e.shiftKey},"*")}evtHandler_(e){const t=e.data,{which:s,shiftKey:i}=t,n=new CustomEvent("control:keydown",{detail:{salt:!0}});n.which=s,n.shiftKey=i,document.dispatchEvent(n)}init_(){const e=function(e){let t={};return(e||location.search.substring(1)).split("&").forEach(e=>{e=e.split("="),t[e[0].toLowerCase()]=e[1]}),t}();if("speaker"===e.mode){this.ws_.el.classList.add("with-note");const e=location.href.replace("mode=speaker","mode=audience"),t=screen.width,s=.8*t,i=`height=${.8*screen.height},width=${s},top=10,left=${(t-s)/2},toolbar=no,menubar=no,location=yes,resizable=yes,scrollbars=no,status=no`;this.listener_=this.popup_=window.open(e,"ppt",i),window.addEventListener("beforeunload",this.closeClient_.bind(this),!1),this.bindEvent_()}else"audience"===e.mode&&(this.listener_=window.opener,this.bindEvent_())}closeClient_(){this.popup_&&this.popup_.close&&this.popup_.close()}}),Y.registerPlugin("speakernote",H);var J=Y;"object"==typeof window&&Array.isArray(window.WSPlugins_)&&WSPlugins_.forEach(({id:e,apply:t})=>{J.registerPlugin(e,t)}),window.WebSlides=J},3645:function(e,t,s){},"379c":function(e,t,s){},9805:function(e,t,s){}}]); -------------------------------------------------------------------------------- /docs/js/chunk-vendors.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * Created by nodeppt 2.2.2 3 | * - Install: npm install -g nodeppt 4 | * - Github: https://github.com/ksky521/nodeppt 5 | */ 6 | -------------------------------------------------------------------------------- /docs/js/index.js: -------------------------------------------------------------------------------- 1 | /*! For license information please see index.js.LICENSE.txt */ 2 | !function(e){function r(r){for(var n,i,l=r[0],f=r[1],p=r[2],c=0,s=[];c 12 | 13 | 14 | # Python 基础教学 {.text-shadow.big-title} 15 | 16 | --- 17 | 18 | By @鹤翔万里(TonyCrane) {.text-intro} 19 | 20 | [:fa-github: Github](https://github.com/TonyCrane/PythonLecture){.button.ghost} 21 | [直播回放](https://www.bilibili.com/video/BV13Z4y1h7x5/){.button.ghost.pink-button} 22 | 23 | ←/→ Space Home End 翻页 24 | 25 | 26 | 27 | # 前言 28 | 29 | --- 30 | 31 | - 这次的教学面向没有学过 python 的人,不论有没有编程基础都可以听懂 32 | - 这里说的东西有些只是为了更好的理解,可能并不严谨,请不要完全听信(~~免责声明~~ 33 | {.description} 34 | 35 | 36 | 37 | # 为什么讲 python 38 | 39 | --- 40 | 41 | - **manim 动画引擎的基础**{.tobuild.fadeInUp} 42 | 43 |   manim 是用 python 编写的库,使用需要有 python 的基础知识(~~不然会被我劝退.jpg~~){.tobuild.fadeInUp} 44 | 45 | - **易用易学、作为工具**{.tobuild.fadeInUp} 46 | 47 |   python 这个语言很易学,特别是对于有编程基础的人(几乎直接上手)。所以有些教程、课程其实过于冗余{.tobuild.fadeInUp} 48 | 49 | - **大学某些课程、老师会默认你会**{.tobuild.fadeInUp} 50 | 51 | 52 | 53 | # 什么是 python 54 | 55 | --- 56 | 57 | ::: shadowbox 58 | 59 | ##  解释性的脚本语言 60 | 61 |   通过解释器来直接运行,不需要编译链接成二进制文件 62 | 63 | --- 64 | 65 | ##  动态类型语言 66 | 67 |   类型在运行时确定,不需要通过代码明文规定 68 | 69 | --- 70 | 71 | ##  面向对象语言 72 | 73 |   python 中一切皆对象 74 | 75 | --- 76 | 77 | ##  ... 78 | 79 | ::: 80 | 81 | 82 | 83 | # 怎么装 python 84 | 85 | --- 86 | 87 | - **装的是什么?**{.tobuild.pulse} 88 | - 是一个 python *解释器*,以及运行需要的*环境*{.tobuild.fadeInUp} 89 | - **怎么装?**{.tobuild.pulse} 90 | - 官方网站 [https\://www.python.org/downloads/](https://www.python.org/downloads/) 91 | {.tobuild.fadeInUp} 92 | - conda(一个好用的 python 环境管理工具){.tobuild.fadeInUp} 93 | - anaconda (大、有预装环境)[https://www.anaconda.com/](https://www.anaconda.com/) 94 | {.tobuild.fadeInUp} 95 | - miniconda (小)[https://docs.conda.io/en/latest/miniconda](https://docs.conda.io/en/latest/miniconda.html) 96 | {.tobuild.fadeInUp} 97 | - **极不建议通过微软应用商店安装 python**{.tobuild.fadeInUp} 98 | - **装什么版本?**{.tobuild.pulse} 99 | - 两个大版本,2.\* 和 3.\*,差别较大,建议 3.\*{.tobuild.fadeInUp} 100 | - 一些小版本,3.6 及之前不推荐,3.7 3.8 稳定,3.9 3.10 完善中,3.11 预览中{.tobuild.fadeInUp} 101 | - 细分版本,选择最新,3.7.13、3.8.13、3.9.12、3.10.4{.tobuild.fadeInUp} 102 | - conda 不必担心版本,默认 3.9,可以通过创建虚拟环境来使用不同版本{.tobuild.fadeInUp} 103 | 104 | 105 | 106 | # 怎么编写、运行 python 107 | 108 | --- 109 | 110 | - **怎么用 python?**{.tobuild.pulse} 111 | - 记住你下载的是一个解释器,建议通过命令行运行 python code.py{.tobuild.fadeInUp} 112 | - **什么是命令行?**{.tobuild.pulse} 113 | - 通过输入命令来通知电脑执行某指令、或者运行某程序{.tobuild.fadeInUp} 114 | - Windows:cmd、Powershell -> 单独运行 / **Windows Terminal** /...{.tobuild.fadeIn} 115 | - macOS:zsh、... -> 终端 / iTerm /...{.tobuild.fadeIn} 116 | - Linux:bash、zsh、... -> 终端 / ...{.tobuild.fadeIn} 117 | - **用什么写代码?**{.tobuild.pulse} 118 | - 记住你编写的只是一个 .py 作为扩展名的文本文件 ~~只要文本编辑器都可以写~~{.tobuild.fadeInUp} 119 | - ~~记事本、自带 IDLE、word~~{.fadeIn} 120 | - Notepad++、Sublime Text{.fadeIn} 121 | - VSCode(Visual Studio Code,不是 VS)[code.visualstudio.com](https://code.visualstudio.com/){.fadeInUp} 122 | - Pycharm(Community Edition 就够用)[jetbrains.com/pycharm](https://www.jetbrains.com/pycharm/){.fadeInUp} 123 | {.build} 124 | 125 | 126 | 127 | # Hello world! 128 | 129 | --- 130 | 131 | ```python 132 | print("Hello world!") 133 | ``` 134 | 135 | 136 | 137 | # 变量 138 | 139 | --- 140 | 141 | - 给一个内容绑定一个标签即变量名(注意请不要认为变量类似一个“盒子”){.tobuild.pulse} 142 | - 通过 = 来定义变量,变量名 = 内容{.tobuild.pulse} 143 | - 动态类型,不需要规定类型(可以通过 `变量名: 类型 = 内容` 来进行类型标注){.tobuild.pulse} 144 | - 变量名{.tobuild.pulse} 145 | - 只能包含字母、数字、下划线、~~中文~~,不能有空格和其它符号{.tobuild.fadeInUp} 146 | - 只能以字母、下划线开头,不能以数字开头,而且大小写敏感{.tobuild.fadeInUp} 147 | - 不能用关键字(例如 if def 等)作为变量名,不推荐使用内置函数名作为变量名{.tobuild.fadeInUp} 148 | - 清晰明确、风格统一{.tobuild.fadeInUp} 149 | - 全大写一般表示常量、不建议使用双下划线开头或者开头结尾、不建议使用 _ 作为变量名{.tobuild.fadeInUp} 150 | 151 | 152 | 153 | # 数字与运算 154 | 155 | --- 156 | 157 | - 1 是整数,1. 是浮点数{.tobuild.pulse} 158 | - 整数与浮点数转换{.tobuild.pulse} 159 | - int(...):向 0 舍入{.tobuild.fadeInUp} 160 | - round(...):向偶舍入(四舍六入五凑偶,可以当成四舍五入){.tobuild.fadeInUp} 161 | - math.floor(...)、math.ceil(...):下取整、上取整(需要 import math){.tobuild.fadeInUp} 162 | - 运算{.tobuild.pulse} 163 | - \+ \- \* 加减乘,左右都是整数结果也是整数,有浮点数结果就是浮点数{.tobuild.fadeInUp} 164 | - / 除法,结果是浮点数(即使可以整除){.tobuild.fadeInUp} 165 | - // 整除,结果是整数,向下取整{.tobuild.fadeInUp} 166 | - % 取模,a % b == a - (a//b)*b(和 c 的行为不一致){.tobuild.fadeInUp} 167 | - \*\* 乘方,可以是浮点数,比如 a \*\* 0.5 表示开根号{.tobuild.fadeInUp} 168 | - pow(a, b, mod):也是乘方,mod 可以省略,如果有 mod 则对结果取模,如果 mod 为 -1 则计算乘法逆元{.tobuild.fadeInUp} 169 | - 更多运算通过 math、numpy、scipy 等包来进行{.tobuild.fadeInUp} 170 | 171 | 172 | 173 | # 复数类型 174 | 175 | --- 176 | 177 | - python 中内置了复数类型,1+2j 形式就表示一个复数,其中 j 即虚数单位 i{.tobuild.fadeIn} 178 | - 或者使用 complex(实部, 虚部) 形式定义复数{.tobuild.fadeIn} 179 | - 可以进行复数的加减乘除运算{.tobuild.fadeIn} 180 | - 属性与方法{.tobuild.pulse} 181 | - c.real:实部{.tobuild.fadeInUp} 182 | - c.imag:虚部{.tobuild.fadeInUp} 183 | - c.conjugate():返回共轭复数{.tobuild.fadeInUp} 184 | 185 | 186 | 187 | # 字符串 188 | 189 | --- 190 | 191 | - 单引号 '...',双引号 "...",三引号 '''...''' """..."""(可以内部换行){.tobuild.pulse} 192 | - \n 换行,\t 制表符,\r 回车,\' 单引号,\" 双引号,\\\\ 斜杠(只打一个 \ 会出问题),……{.tobuild.pulse} 193 | - 前缀{.tobuild.pulse} 194 | - r-string:r"...",引号中不进行转义,即一个 \ 就代表斜杠字符本身{.tobuild.fadeInUp} 195 | - f-string:f"...",格式化字符串{.tobuild.fadeInUp} 196 | - b-string:b"...",将字符串转为 bytes,只能包含 ASCII 字符{.tobuild.fadeInUp} 197 | - 常用方法{.tobuild.pulse} 198 | - 拼接:直接将字符串“相加”{.tobuild.fadeInUp} 199 | - "...".upper()、"...".lower():转为全大写、全小写{.tobuild.fadeInUp} 200 | - "...".title():单词首字母大写{.tobuild.fadeInUp} 201 | - "...".strip():删除字符串首尾空白(包含空格和制表符){.tobuild.fadeInUp} 202 | - "...".lstrip()、"...".rstrip():删除左、右端空白{.tobuild.fadeInUp} 203 | - "...".split(c):根据字符 c 来拆分字符串得到列表,默认拆分空白{.tobuild.fadeInUp} 204 | 205 | 206 | 207 | # f-string 208 | 209 | --- 210 | 211 | - 格式化字符串方式:"..." % ...,"...".format(...),f"..."{.tobuild.pulse} 212 | - 字符串内大括号括起来的计算后转为字符串填入 f"...{...}..."{.tobuild.pulse} 213 | - 如果字符串要用大括号原始字符要写两个 f"...{{..."{.tobuild.pulse} 214 | - 格式化(在填入内容后面加冒号 f"...{表达式:格式}..."){.tobuild.pulse} 215 | - 宽度填充:\:[填充字符][对齐方式][宽度],< 左对齐,> 右对齐,^ 居中{.tobuild.fadeInUp} 216 | - 字符截断:\:[...].n,只显示字符串的前 n 个字符{.tobuild.fadeInUp} 217 | - 数值符号:\:+ 正数加正号、负数加负号,\:- 原样,\: (空格)正数加空格、负数加负号{.tobuild.fadeInUp} 218 | - 数值精度:\:[宽度][分隔符(,_)].[精度]f,没有精度默认为 6{.tobuild.fadeInUp} 219 | - 进制显示:x 小写十六进制,X 大写十六进制,o 八进制,b 二进制,加 # 显示前缀{.tobuild.fadeInUp} 220 | 221 | 222 | 223 | # 字节类型 224 | 225 | --- 226 | 227 | - 类似字符串,但存储的是字节的值,更像列表,显示为 b"..." 只是更加易读而已{.tobuild.pulse} 228 | - b"..." 则表示字节类型,其中只能包含 ASCII 字符和 \x.. 表示的十六进制数{.tobuild.pulse} 229 | - 与字符串转换{.tobuild.pulse} 230 | - "...".encode(encoding) 根据 encoding 编码字符串,默认 UTF-8{.tobuild.fadeInUp} 231 | - bytes_obj.decode(encoding) 根据 encoding 解码字节序列,解码失败会报错{.tobuild.fadeInUp} 232 | - bytes("...", encoding) 也是根据 encoding 编码字符串{.tobuild.fadeInUp} 233 | - 不要使用 str(b"...") 来将字节序列转为字符串{.tobuild.fadeInUp} 234 | 235 | 236 | 237 | # 布尔类型 238 | 239 | --- 240 | 241 | - True 和 False,记住首字母大写{.tobuild.fadeInUp} 242 | - 用 bool(...) 来转换,如果是数字则非零都是 True,如果是字符串则非空都是 True{.tobuild.fadeInUp} 243 | - 运算{.tobuild.pulse} 244 | - 可以使用 & | 来表示与和或(但并不会短路){.tobuild.fadeInUp} 245 | - 一般使用 and or not 进行与/或/非运算(会短路){.tobuild.fadeInUp} 246 | 247 | ----- 248 | 249 | # 注释{.tobuild.fadeIn} 250 | 251 | --- 252 | 253 | - 单行注释一个 #{.tobuild.fadeInUp} 254 | - 严格上并没有多行注释,但可以用 """ 字符串来代替(因为这样不影响运行){.tobuild.fadeInUp} 255 | 256 | 257 | 258 | # 列表 259 | 260 | --- 261 | 262 | - 类似其它语言的数组,但是功能更多,而且内部元素不要求同一类型{.tobuild.fadeInUp} 263 | - 方括号 [] 表示列表,元素用逗号分隔{.tobuild.fadeInUp} 264 | - 索引(即下标)从 0 开始计数,lst[n] 即表示访问第 n+1 个元素{.tobuild.fadeInUp} 265 | - 索引可以是负数,负数即表示倒数,例 lst[-2] 表示倒数第二个元素{.tobuild.fadeInUp} 266 | - 切片(获取列表中的一部分值){.tobuild.pulse} 267 | - lst[a\:b]:从 lst[a] 到 lst[b-1] 的列表 268 | - lst[\:b]:从开头到 lst[b-1] 的列表 269 | - lst[a\:]:从 lst[a] 到结尾的列表 270 | - lst[\:]:表示整个列表(拷贝一份) 271 | - lst[a\:b\:c]:从 lst[a] 到 lst[b-1] 每 c 个(即步长)取一个形成的列表 272 | - c 可以是负数,此时需要 a > b 才能获取到值 273 | - 有步长时若省略 a、b 记得不要省略冒号,例 lst[\:\:-1] 表示列表倒序 274 | {.build.fadeIn} 275 | 276 | 277 | 278 | # 列表操作 279 | 280 | --- 281 | 282 | - 修改元素:直接通过索引/切片,然后等号赋值{.tobuild.fadeInUp} 283 | - 有栈的功能{.tobuild.pulse} 284 | - lst.append(...) 在列表末尾加入元素{.tobuild.fadeInUp} 285 | - lst.pop() 弹出列表末尾元素并返回{.tobuild.fadeInUp} 286 | - 任意位置插入弹出{.tobuild.pulse} 287 | - lst.insert(i, x) 在索引 i 的位置插入 x,后面依次后移{.tobuild.fadeInUp} 288 | - lst.pop(i) 弹出索引 i 位置的元素,后面依次前移{.tobuild.fadeInUp} 289 | - 列表拼接{.tobuild.pulse} 290 | - 直接相加,不改变原列表,得到新的列表{.tobuild.fadeInUp} 291 | - lst.extend([...]),把一个列表接到当前列表后面{.tobuild.fadeInUp} 292 | - 根据值删除元素{.tobuild.pulse} 293 | - lst.remove(value) 删除第一个值为 value 的元素{.tobuild.fadeInUp} 294 | 295 | 296 | 297 | # 列表操作 298 | 299 | --- 300 | 301 | - 排序列表{.tobuild.pulse} 302 | - lst.sort() 永久排序(即排序后赋值给当前列表){.tobuild.fadeInUp} 303 | - sorted(lst) 临时排序,返回排序好的新列表{.tobuild.fadeInUp} 304 | - 默认从小到大,如果传入 reverse=True 则从大到小{.tobuild.fadeInUp} 305 | - 反转列表{.tobuild.pulse} 306 | - lst.reverse() 永久反转(意义同上){.tobuild.fadeInUp} 307 | - lst[\:\:-1] 返回反转的列表(利用前面说到的切片){.tobuild.fadeInUp} 308 | - 统计操作{.tobuild.pulse} 309 | - len(lst) 得到列表的长度{.tobuild.fadeInUp} 310 | - sum(lst) 得到列表的元素和(本质上是将 start 参数和每个元素依次相加){.tobuild.fadeInUp} 311 | - 可以传入 start 参数用来指定加和的起始值 312 | - max(lst) 得到列表中的最大值{.tobuild.fadeInUp} 313 | - min(lst) 得到列表中的最小值{.tobuild.fadeInUp} 314 | 315 | 316 | 317 | # 元组 318 | 319 | --- 320 | 321 | - 可以看成元素不可变的列表,内部也可以包含不同类型的元素{.tobuild.fadeIn} 322 | - 括号表示元组,内部元素间用逗号分隔{.tobuild.fadeIn} 323 | - 可以使用和列表一样的方法来读取元素,但并不能修改{.tobuild.fadeIn} 324 | - 当只有一个元素的时候要写成 (a,) 而不是 (a)(后者是单个值){.tobuild.fadeIn} 325 | - 可以使用 tuple(...) 来将可迭代对象(列表、字符串等)转为元组{.tobuild.fadeIn} 326 | - 元组并不能保证元素完全不可变{.tobuild.fadeIn} 327 | - 避免在元组中存放可变元素 328 | 329 | 330 | 331 | # 集合 332 | 333 | --- 334 | 335 | - 大括号括起来,内部元素间用逗号分隔,会自动去重{.tobuild.fadeIn} 336 | - 可用 set(...) 来将可迭代对象转为元组,自动去重{.tobuild.fadeIn} 337 | - 集合中不能包含列表等不可 hash 化的元素{.tobuild.fadeIn} 338 | - 修改{.tobuild.pulse} 339 | - s.add(...) 来加入一个元素{.tobuild.fadeInUp} 340 | - s.remove(...) 删除一个元素,如果没有会抛出异常{.tobuild.fadeInUp} 341 | - s.discard(...) 来删除一个元素,如果没有则忽略{.tobuild.fadeInUp} 342 | - 运算{.tobuild.pulse} 343 | - s1 & s2、s1 | s2、s1 - s2 交集、并集、差集{.tobuild.fadeInUp} 344 | - s1 ^ s2 对称差集{.tobuild.fadeInUp} 345 | 346 | 347 | 348 | # 字典 349 | 350 | --- 351 | 352 | - 存储键值对,也是大括号括起来,不过逗号分隔的是键值对 {key: value, ...}{.tobuild.fadeIn} 353 | - {} 是空字典而不是空集合{.tobuild.fadeIn} 354 | - 通过 d[key] 来访问字典中 key 对应的值,可以读取、修改{.tobuild.fadeIn} 355 | - 添加键值对可以直接通过 d[key] = value 来进行{.tobuild.fadeIn} 356 | - 删除键值对可以直接 del d[key]{.tobuild.fadeIn} 357 | - 通过 d[key] 访问值时如果不存在 key 这个键会抛出异常{.tobuild.fadeIn} 358 | - 通过 d.get(key) 来访问值时如果不存在则会返回 None 359 | - 使用 d.get(key, default) 如果没有 key 时会返回 default 值 360 | {.tobuild.fadeInUp} 361 | - d.update(d2) 来用 d2 中的键值对更新 d{.tobuild.fadeIn} 362 | 363 | 364 | 365 | # 布尔表达式 366 | 367 | --- 368 | 369 | - `==` 判断相等(相等则返回 True),`!=` 判断不等{.tobuild.fadeIn} 370 | - 使用 and or not 来进行布尔运算,必要时加括号保证优先级{.tobuild.fadeIn} 371 | - 数值比较大小 `< <= > >=` {.tobuild.fadeIn} 372 | - 判断元素是否在列表中{.tobuild.fadeIn} 373 | - value in lst:如果在则值为 True 374 | - value not in lst:如果在则为 False(判断是否不在) 375 | {.tobuild.fadeInUp} 376 | - 判断键是否在字典中{.tobuild.fadeIn} 377 | - key in d、key not in d 与列表同理 378 | 379 | 380 | 381 | :::{.content-left} 382 | 383 | # 条件语句 384 | 385 | --- 386 | 387 | - if-elif-else 结构(不是 else if) 388 | - elif、else 均可以省略{.tobuild.fadeIn} 389 | - 条件不需要加括号(加了也没问题){.tobuild.fadeIn} 390 | - condition 会被转换成 bool 类型然后判断{.tobuild.fadeIn} 391 | - 注意缩进{.tobuild.fadeIn} 392 | - 类三目运算符写法 a if condition else b{.tobuild.fadeIn} 393 | - 类似其它语言中的 condition? a \: b 394 | 395 | ::: 396 | 397 | :::{.content-right} 398 | 399 | ```python 400 | if condition1: 401 | ... 402 | elif condition2: 403 | ... 404 | elif condition3: 405 | ... 406 | else: 407 | ... 408 | ``` 409 | 410 | 411 | 412 | # 缩进 413 | 414 | --- 415 | 416 | - 缩进是 python 中很重要的东西,python 靠缩进来得到代码结构,而不是大括号{.tobuild.fadeIn} 417 | - 缩进可以使用空格或制表符{.tobuild.fadeIn} 418 | - 如果一些代码处于同一层缩进下,则属于同一个代码块{.tobuild.fadeIn} 419 | - 同一个代码块的缩进要统一{.tobuild.fadeIn} 420 | - 不仅仅是看着像,要区分好空格与制表符 421 | - 4 个空格与一个显示宽度为 4 的制表符并不是同一缩进 422 | - 一般使用 4 空格缩进,或者 1 制表符缩进{.tobuild.fadeIn} 423 | - 编辑器中按 Tab 打出的也不一定是制表符,要分清{.tobuild.fadeIn} 424 | - 缩进不正确会报 IndentationError,此时注意检查缩进{.tobuild.fadeIn} 425 | 426 | 427 | 428 | :::{.content-left} 429 | 430 | # for 循环 431 | 432 | --- 433 | 434 | - python 中的 for 循环并不像 c 中是指定一个变量的变化方式,而是从列表/元组/迭代器等可迭代对象中遍历值 435 | - for 循环会产生一个用于循环的变量,这个变量在循环结束后并不会删除,而是保留最后一次的值{.tobuild.fadeIn} 436 | - 可以使用 range 来生成一串数字用来循环{.tobuild.fadeIn} 437 | - range(a, b) 生成从 a 到 b-1 的连续整数{.tobuild.fadeInUp} 438 | - range(a, b, c) 以 c 为步长生成{.tobuild.fadeInUp} 439 | - range 得到的并不是列表,如果要用其生成列表要使用 list(range(...)){.tobuild.fadeInUp} 440 | 441 | ::: 442 | 443 | :::{.content-right} 444 | ```python 445 | for value in lst: 446 | ... 447 | 448 | for value in range(...): 449 | ... 450 | ``` 451 | 452 | 453 | 454 | :::{.content-left} 455 | 456 | # for 循环遍历字典 457 | 458 | --- 459 | 460 | - 有三种方法来遍历字典 461 | - 在 d.keys() 中循环遍历所有键{.tobuild.fadeIn} 462 | - 在 d.values() 中循环遍历所有值{.tobuild.fadeIn} 463 | - 在 d.items() 中遍历键值对(需要解包){.tobuild.fadeIn} 464 | 465 | ::: 466 | 467 | :::{.content-right} 468 | ```python 469 | for key in d.keys(): 470 | ... 471 | 472 | for value in d.values(): 473 | ... 474 | 475 | for item in d.items(): 476 | ... # item 为一个元组 477 | 478 | for key, value in d.items(): 479 | ... # 将 item 解包 480 | ``` 481 | 482 | 483 | 484 | :::{.content-left} 485 | 486 | # 元素解包 487 | 488 | --- 489 | 490 | - 赋值时等号左侧可以是用逗号分隔的多个值,这时会将右侧解包分别赋值给左侧的各个变量 491 | - 右侧也可以是多个值(只要出现逗号就会视为一个元组){.tobuild.fadeIn} 492 | - 可以通过 a, b = b, a 实现元素交换 493 | - 星号表达式{.tobuild.fadeIn} 494 | - 可以用来在可迭代对象内部解包 495 | - 也可用来标记一个变量包含多个值 496 | - for 循环可以解包{.tobuild.fadeIn} 497 | 498 | ::: 499 | 500 | :::{.content-right} 501 | ```python 502 | t = (1, 2, 3) 503 | a, b, c = t # a = 1, b = 2, c = 3 504 | t = (1, 2, (3, 4)) 505 | a, b, (c, d) = t # c = 3, d = 4 506 | 507 | l = [1, 2, *[3, 4]] # [3, 4] 被解包 508 | # l = [1, 2, 3, 4] 509 | a, *b = [1, 2, 3, 4] 510 | # a = 1, b = [2, 3, 4] 511 | 512 | lst = [[1, 2], [3, 4]] 513 | for a, b in lst: 514 | ... # 第一次循环 a, b 为 1, 2 515 | # 第二次循环 a, b 为 3, 4 516 | ``` 517 | 518 | 519 | 520 | :::{.content-left} 521 | 522 | # for 循环技巧 523 | 524 | --- 525 | 526 | - enumerate 计数{.tobuild.fadeIn} 527 | - 可以指定初始值 528 | - zip 同时循环多个可迭代对象{.tobuild.fadeIn} 529 | - 循环次数为最短的对象的长度 530 | 531 | ::: 532 | 533 | :::{.content-right} 534 | ```python 535 | for i, value in enumerate(lst): 536 | ... # i 依次为 0,1,2,…… 537 | 538 | for i, value in enumerate(lst, 1): 539 | ... # i 依次为 1,2,3,…… 540 | 541 | for a, b in zip(lst1, lst2): 542 | ... # a 在 lst1 中循环 543 | # b 在 lst2 中循环 544 | ``` 545 | 546 | 547 | 548 | :::{.content-left} 549 | 550 | # 列表推导 551 | 552 | --- 553 | 554 | - 一种很方便的生成列表的方式 555 | - 即在列表中包含循环,逐次记录循环前表达式的值{.tobuild.fadeIn} 556 | - 可以有多重循环,即生成笛卡尔积{.tobuild.fadeIn} 557 | - 可以包含条件,即在条件成立时才记录值{.tobuild.fadeIn} 558 | - 列表推导中的循环变量有局部作用域{.tobuild.fadeIn} 559 | - 即在列表推导外不能访问循环变量 560 | 561 | ::: 562 | 563 | :::{.content-right} 564 | ```python 565 | lst = [] 566 | for i in range(1, 10): 567 | lst.append(i**2) 568 | # 等价于 569 | lst = [i**2 for i in range(1, 10)] 570 | 571 | lst1 = [x*y for x in l1 for y in l2] 572 | 573 | lst2 = [... for ... in ... if ...] 574 | ``` 575 | 576 | 577 | 578 | :::{.content-left} 579 | 580 | # 生成元组/字典 581 | 582 | --- 583 | 584 | - 可以使用和列表推导类似的方法生成元组和字典 585 | - 生成元组的时候要用 tuple(){.tobuild.fadeIn} 586 | - 只写 () 的话则只是生成器表达式 587 | - 生成字典时循环前用 \: 将键值隔开{.tobuild.fadeIn} 588 | 589 | ::: 590 | 591 | :::{.content-right} 592 | ```python 593 | tuple(i**2 for i in range(1, 10)) 594 | 595 | (i**2 for i in range(1, 10)) 596 | # ^ generator object 597 | 598 | {a: b for a in ... for b in ... } 599 | ``` 600 | 601 | 602 | 603 | :::{.content-left} 604 | 605 | # 控制循环 606 | 607 | --- 608 | 609 | - 和其它语言一样,在循环代码块中可以控制循环的进行{.tobuild.fadeIn} 610 | - break 立刻结束循环{.tobuild.fadeIn} 611 | - continue 立刻进行下一轮循环{.tobuild.fadeIn} 612 | 613 | ::: 614 | 615 | :::{.content-right} 616 | 617 | # while 循环{.tobuild.fadeIn} 618 | 619 | --- 620 | 621 | - while 循环即进行条件检查,如果为 True 则继续运行直到条件不满足停止{.tobuild.fadeIn} 622 | 623 | ```python{.tobuild.fadeIn} 624 | while condition: 625 | ... 626 | ``` 627 | 628 | 629 | 630 | :::{.content-left} 631 | 632 | # 函数定义 633 | 634 | --- 635 | 636 | - 使用 def 关键字来定义函数 637 | - 先函数名,然后括号列出参数,下面接代码块{.tobuild.fadeIn} 638 | - 使用 return 返回{.tobuild.fadeIn} 639 | - 没有 return 运行到结尾,返回 None{.tobuild.fadeInUp} 640 | - 只有 return,返回 None{.tobuild.fadeInUp} 641 | - return 后接内容,返回内容{.tobuild.fadeInUp} 642 | - return 的值类型不要求一致{.tobuild.fadeInUp} 643 | - return 可以返回多个值(利用元组){.tobuild.fadeInUp} 644 | 645 | ::: 646 | 647 | :::{.content-right} 648 | ```python 649 | def func_name(arg1, arg2): 650 | ... 651 | 652 | def func_name(arg1, arg2): 653 | ... 654 | return ... 655 | 656 | def func_name(arg1, arg2): 657 | ... 658 | return ..., ... 659 | ``` 660 | 661 | 662 | 663 | :::{.content-left} 664 | 665 | # 函数参数 666 | 667 | --- 668 | 669 | - 括号中要列出参数名,供函数体内使用{.tobuild.fadeIn} 670 | - 可以在参数后接等号赋默认值{.tobuild.fadeIn} 671 | - 使用默认值的参数在调用时可以不用传 672 | - 利用 \* 来接收任意多参数{.tobuild.fadeIn} 673 | - 接收进来是一个元组 674 | - \* 参数后面不能再有其它非关键字参数 675 | - 利用 \*\* 来接收任意多关键字参数{.tobuild.fadeIn} 676 | - 接收进来是一个字典 677 | 678 | ::: 679 | 680 | :::{.content-right} 681 | ```python 682 | def func(arg1, arg2): 683 | ... 684 | 685 | def func(arg1, arg2="..."): # 默认值 686 | ... 687 | 688 | def func(arg1, *arg2): # 任意多参数 689 | ... 690 | 691 | def func(arg1, **arg2): # 任意多关键字参数 692 | ... 693 | 694 | def func(arg1, *arg2, **arg3): 695 | ... # *arg2 后可以加 **arg3 696 | ``` 697 | 698 | 699 | 700 | :::{.content-left} 701 | 702 | # 函数调用 703 | 704 | --- 705 | 706 | - 通过 函数名(参数) 来调用函数,得到返回值{.tobuild.fadeIn} 707 | - 直接传参的话要将参数与定义对应上{.tobuild.fadeIn} 708 | - 通过关键字传参(参数名)可以打乱顺序{.tobuild.fadeIn} 709 | - 带有默认值的参数如果不传则使用默认值{.tobuild.fadeIn} 710 | - 如果读任意多关键字参数,则多余的读到字典中{.tobuild.fadeIn} 711 | 712 | ::: 713 | 714 | :::{.content-right} 715 | ```python 716 | def func(a, b): 717 | ... 718 | 719 | func(1, 2) # a = 1, b = 2 720 | func(b=1, a=2) # a = 2, b = 1 721 | 722 | def func2(a, **b): 723 | ... 724 | 725 | func2(a=1, b=2, c=3) 726 | # a = 1, b = {"b": 2, "c": 3} 727 | ``` 728 | 729 | 730 | 731 | # 引用变量 732 | 733 | --- 734 | 735 | - python 中的变量都是引用的(这也就是为什么前面说不要将变量理解为盒子){.tobuild.fadeIn} 736 | - 用 = 实际上是定义了一个别名{.tobuild.fadeIn} 737 | - lst1 = lst2,则 lst1 和 lst2 会同时变化(要用 [\:] 创建副本){.tobuild.fadeInUp} 738 | - 数值类型有优化,所以不会这样{.tobuild.fadeInUp} 739 | - `==` 检查值是否相等,is 检查值是否相同{.tobuild.fadeInUp} 740 | - 观察 [pythontutor.com](https://pythontutor.com/) {.tobuild.fadeInUp} 741 | - 函数参数传递只有“共享传参”一种形式(即传引用){.tobuild.fadeIn} 742 | - 可变变量(例如列表)在函数内部可以被改变{.tobuild.fadeInUp} 743 | - 避免向函数传递可变变量(列表可传入 [\:] 创建的副本){.tobuild.fadeInUp} 744 | 745 | 746 | 747 | :::{.content-left} 748 | 749 | # 匿名函数 750 | 751 | --- 752 | 753 | - 可以通过 lambda 表达式来定义匿名函数{.tobuild.fadeIn} 754 | - lambda 输入\: 输出表达式{.tobuild.fadeIn} 755 | - 可以有多个输入{.tobuild.fadeIn} 756 | - 可以将一个函数赋值给一个变量{.tobuild.fadeIn} 757 | - 避免用 lambda 赋值的形式定义函数{.tobuild.fadeIn} 758 | - 例如 \_\_name\_\_ 属性不会是函数名,而是 "\" 759 | 760 | ::: 761 | 762 | :::{.content-right} 763 | ```python 764 | lambda a: a**2 + 2*a + 1 765 | (lambda a: a**2 + 2*a + 1)(2) # 9 766 | 767 | lambda a, b: a*2 + b 768 | 769 | f = lambda a: a**2 + 2*a + 1 770 | # 近似等价于 771 | def f(a): 772 | return a**2 + 2*a + 1 773 | ``` 774 | 775 | 776 | 777 | :::{.content-left} 778 | 779 | # 用户输入 780 | 781 | --- 782 | 783 | - 读取用户输入使用内置的 input 函数{.tobuild.fadeIn} 784 | - 函数参数为要显示的提示符,例如 input("> "){.tobuild.fadeIn} 785 | - 函数的返回值为一个字符串{.tobuild.fadeIn} 786 | - 每次读入一行(即读到换行为止){.tobuild.fadeIn} 787 | 788 | ::: 789 | 790 | :::{.content-right} 791 | 792 | # 高阶函数用法{.tobuild.fadeIn} 793 | 794 | --- 795 | 796 | - 接收函数作为参数的函数被称为高阶函数{.tobuild.fadeIn} 797 | - 比较常用的有 map、filter{.tobuild.fadeIn} 798 | 799 | ```python{.tobuild.fadeIn} 800 | list(map(lambda x: x*2, [1, 2])) 801 | # [2, 4] 802 | list(filter(lambda x: x>1, [1, 2, 3])) 803 | # [2, 3] 804 | ``` 805 | 806 | 807 | 808 | :::{.content-left} 809 | 810 | # 类 811 | 812 | --- 813 | 814 | - 类可以看成包含一些**属性**和**方法**的框架{.tobuild.fadeIn} 815 | - 根据类来创建对象 -> 实例化{.tobuild.fadeIn} 816 | - 用 class 关键字来定义类{.tobuild.fadeIn} 817 | - 类中的函数 -> 方法{.tobuild.fadeIn} 818 | - 特殊方法 \_\_init\_\_,在类实例化的时候会被自动调用 819 | - 其它一般的方法第一个参数都要为"self",调用的时候会自动传入 820 | - 直接写在类中的是属性,也可以通过为 self.\ 赋值的形式创建属性{.tobuild.fadeIn} 821 | - 用类似函数调用的形式实例化类,参数为\_\_init\_\_方法的参数{.tobuild.fadeIn} 822 | - 直接通过 .\ .\ 的形式调用方法/获取属性{.tobuild.fadeIn} 823 | 824 | ::: 825 | 826 | :::{.content-right} 827 | ```python 828 | class ClassName(): 829 | a = 1 830 | def __init__(self, arg1, arg2): 831 | self.arg1 = arg1 832 | self.arg2 = arg2 833 | def method(self): 834 | print(self.arg1, self.arg2, self.a) 835 | 836 | obj = ClassName(2, 3) 837 | obj.method() # 2 3 1 838 | print(obj.a, obj.arg1) # 1 2 839 | ``` 840 | 841 | 842 | 843 | :::{.content-left} 844 | 845 | # 类的继承 846 | 847 | --- 848 | 849 | - 在 class 定义的括号中加上另一个类名则表示继承自那个类定义一个子类{.tobuild.fadeIn} 850 | - 子类会继承父类的所有属性和方法{.tobuild.fadeIn} 851 | - 子类编写和父类名字一样的方法会**重载**{.tobuild.fadeIn} 852 | - 在重载的方法中调用父类的原方法使用 super(){.tobuild.fadeIn} 853 | - 也可以为子类定义独有的方法{.tobuild.fadeIn} 854 | 855 | ::: 856 | 857 | :::{.content-right} 858 | ```python 859 | class ClassA(): 860 | def __init__(self, a): 861 | self.a = a 862 | def print(self): 863 | print(self.a) 864 | 865 | class ClassB(ClassA): 866 | def __init__(self, a): 867 | super().__init__(a) 868 | self.a *= 2 869 | 870 | obj = ClassB(1) 871 | obj.print() # 2 872 | ``` 873 | 874 | 875 | 876 | :::{.content-left} 877 | 878 | # 私有? 879 | 880 | --- 881 | 882 | - python 中类并没有严格私有的属性{.tobuild.fadeIn} 883 | - 双下划线开头的属性会被隐藏,不能直接读取{.tobuild.fadeIn} 884 | - 但这种属性可以通过 _类名__属性 但方式读取到{.tobuild.fadeIn} 885 | - 使用双下划线开头的属性可以轻微保护属性,但并不代表其是私有的{.tobuild.fadeIn} 886 | 887 | ::: 888 | 889 | :::{.content-right} 890 | ```python 891 | class A(): 892 | a = 1 893 | _a = 2 894 | __a = 3 895 | 896 | obj = A() 897 | print(obj.a) # 1 898 | print(obj._a) # 2 899 | print(obj.__a) # AttributeError 900 | print(obj._A__a) # 3 901 | ``` 902 | 903 | 904 | 905 | # 一切皆对象? 906 | 907 | --- 908 | 909 | - python 中即使最简单的整数也是一个类的实例{.tobuild.fadeIn} 910 | - 通过 dir(...) 查看一个对象的所有属性/方法{.tobuild.fadeIn} 911 | - 有很多双下划线开头、双下划线结尾的方法,成为魔术方法(dunder method){.tobuild.fadeIn} 912 | 913 | 914 | 915 | :::{.content-left} 916 | 917 | # 魔术方法 918 | 919 | --- 920 | 921 | - 很多函数、表达式其实是通过调用类的魔术方法来实现的{.tobuild.fadeIn} 922 | - len(obj) 调用 obj.\_\_len\_\_(){.tobuild.fadeInUp} 923 | - obj[...] 调用 obj.\_\_getitem\_\_(...){.tobuild.fadeInUp} 924 | - a in obj 调用 obj.\_\_contains\_\_(a){.tobuild.fadeInUp} 925 | - bool(obj) 调用 obj.\_\_bool\_\_(){.tobuild.fadeInUp} 926 | - 函数的调用本质上是调用 func.\_\_call\_\_(){.tobuild.fadeInUp} 927 | - a + b 调用 a.\_\_add\_\_(b){.tobuild.fadeInUp} 928 | - ......{.tobuild.fadeInUp} 929 | 930 | ::: 931 | 932 | :::{.content-right} 933 | 934 | 一个例子:{.tobuild.fadeIn} 935 | 936 | - lst[a\:b\:c] 切片操作{.tobuild.fadeIn} 937 | - 其中切片也是一个对象,它是一个 slice 类的实例{.tobuild.fadeIn} 938 | - 所以它等价于 lst[slice(a, b, c)] 939 | - 而通过 [] 的操作又是通过 \_\_getitem\_\_ 魔术方法实现的{.tobuild.fadeIn} 940 | - 所以它又等价于 lst.\_\_getitem\_\_(slice(a, b, c)) 941 | - \_\_getitem\_\_ 方法中处理了 slice,读取 abc 的值,再处理返回一个新列表{.tobuild.fadeIn} 942 | 943 | 944 | 945 | # 就这? 946 | 947 | --- 948 | 949 | - python 中类还有更多更多更好玩的用法{.tobuild.pulse} 950 | - 静态方法、类方法……{.tobuild.fadeInUp} 951 | - 多重继承、mro 顺序……{.tobuild.fadeInUp} 952 | - 接口协议、鸭子类型、抽象基类……{.tobuild.fadeInUp} 953 | - 猴子补丁……{.tobuild.fadeInUp} 954 | - 元类……{.tobuild.fadeInUp} 955 | - 垃圾回收……{.tobuild.fadeInUp} 956 | - .......{.tobuild.fadeInUp} 957 | 958 | 959 | 960 | 961 | :::{.content-left} 962 | # 文件操作 963 | 964 | --- 965 | 966 | - open 函数,传入文件名、打开模式{.tobuild.fadeIn} 967 | - 打开模式(可以叠加):r 读(默认)、w 写、x 创建并写、a 写在末尾、b 字节模式、t 文本模式(默认){.tobuild.fadeIn} 968 | - 读取{.tobuild.pulse} 969 | - 文本模式建议加上 encoding,不然容易报错{.tobuild.fadeInUp} 970 | - f.read() 读取全部内容(字节模式得到字节序列){.tobuild.fadeInUp} 971 | - f.readline() 读取一行{.tobuild.fadeInUp} 972 | - f.readlines() 读取所有行,返回一个列表{.tobuild.fadeInUp} 973 | - 写入{.tobuild.pulse} 974 | - 文本模式同样建议加上 encoding{.tobuild.fadeInUp} 975 | - f.write(...) 直接写入{.tobuild.fadeInUp} 976 | - f.writelines(...) 传入列表,元素间换行写入{.tobuild.fadeInUp} 977 | - 通过这种形式操作文件记得用完后要 f.close(){.tobuild.fadeIn} 978 | 979 | ::: 980 | 981 | :::{.content-right} 982 | ```python {.small-code} 983 | f = open("filename", "r", encoding="utf-8") 984 | s = f.read() # a str 985 | # line = f.readline() # a str 986 | # lines = f.readlines() # a list 987 | ... 988 | f.close() 989 | 990 | f = open("filename", "w", encodeing="utf-8") 991 | f.write("...") 992 | f.writelines(["...", "..."]) 993 | ... 994 | f.close() 995 | ``` 996 | 997 | 998 | 999 | :::{.content-left} 1000 | 1001 | # with 块 1002 | 1003 | --- 1004 | 1005 | - with ... as ...\: 开启一个上下文管理器{.tobuild.fadeIn} 1006 | - 常用在文件 open 上{.tobuild.fadeIn} 1007 | - with 块开始自动打开 1008 | - with 块结束自动结束 1009 | - with 块结束后变量仍会留存{.tobuild.fadeIn} 1010 | 1011 | ::: 1012 | 1013 | :::{.content-right} 1014 | ```python {.small-code} 1015 | with open("file", "r", encoding="utf-8") as f: 1016 | s = f.read() 1017 | ... 1018 | 1019 | print(f.closed) # True 1020 | ``` 1021 | 1022 | 1023 | 1024 | :::{.content-left} 1025 | 1026 | # 异常与处理 1027 | 1028 | --- 1029 | 1030 | - 产生错误 -> 抛出异常 -> 程序结束{.tobuild.fadeIn} 1031 | - raise 关键字抛出异常{.tobuild.fadeIn} 1032 | - try-except 块捕获异常{.tobuild.fadeIn} 1033 | - 可以有多个 except、不可以没有{.tobuild.fadeInUp} 1034 | - except 后接异常类(没有则捕获所有){.tobuild.fadeInUp} 1035 | - as 字句存下异常{.tobuild.fadeInUp} 1036 | - finally 语句{.tobuild.fadeIn} 1037 | - 不管是否有异常都会运行 1038 | 1039 | ::: 1040 | 1041 | :::{.content-right} 1042 | ```python 1043 | raise ... 1044 | raise RuntimeError("...") 1045 | 1046 | try: 1047 | input(">>> ") 1048 | except KeyboardInterrupt: 1049 | print("Good bye") 1050 | 1051 | try: 1052 | print(1 / 0) 1053 | except ZeroDivisionError as e: 1054 | print("can't devide by zero") 1055 | raise e 1056 | finally: 1057 | print("finished") 1058 | ``` 1059 | 1060 | 1061 | 1062 | :::{.content-left} 1063 | 1064 | # if 外的 else 语句 {.small-h1} 1065 | 1066 | --- 1067 | 1068 | - else 块不仅仅跟着 if 才能使用{.tobuild.fadeIn} 1069 | - for-else{.tobuild.fadeIn} 1070 | - for 循环结束才会运行 1071 | - for 循环被 break 了不会运行 1072 | - while-else{.tobuild.fadeIn} 1073 | - condition 不成立退出才会运行 1074 | - 循环被 break 终止了不会运行 1075 | - try-else{.tobuild.fadeIn} 1076 | - try 块中没有异常出现才会运行 1077 | - else 块中异常不会被前面的 except 捕获 1078 | - 程序流跳到块外了不会运行(return 等){.tobuild.fadeIn} 1079 | 1080 | ::: 1081 | 1082 | :::{.content-right} 1083 | ```python 1084 | for value in lst: 1085 | ... 1086 | else: 1087 | ... 1088 | 1089 | while condition: 1090 | ... 1091 | else: 1092 | ... 1093 | 1094 | try: 1095 | ... 1096 | except ...: 1097 | ... 1098 | else: 1099 | ... 1100 | ``` 1101 | 1102 | 1103 | 1104 | 1105 | :::{.content-left} 1106 | 1107 | # 模块与导入 1108 | 1109 | --- 1110 | 1111 | - 模块可以是一个单独的 .py 文件,也可以是一个文件夹{.tobuild.fadeIn} 1112 | - 文件夹相当于导入其下 \_\_init\_\_.py 文件 1113 | - 模块中正常编写函数、类、语句{.tobuild.fadeIn} 1114 | - 通过 import 语句导入模块{.tobuild.fadeIn} 1115 | - import code{.tobuild.fadeInUp} 1116 | - import code as cd{.tobuild.fadeInUp} 1117 | - from code import ...{.tobuild.fadeInUp} 1118 | - from code import *{.tobuild.fadeInUp} 1119 | - 导入时相当于运行了一遍导入的代码{.tobuild.fadeIn} 1120 | 1121 | ::: 1122 | 1123 | :::{.content-right} 1124 | ```python 1125 | # code.py 1126 | print("hello") 1127 | def f(): 1128 | print("call func in code.py") 1129 | ... 1130 | ``` 1131 | ```python 1132 | import code # hello 1133 | code.f() 1134 | import code as cd # hello 1135 | cd.f() 1136 | from code import f # hello 1137 | f() 1138 | from code import * # hello 1139 | f() 1140 | ``` 1141 | 1142 | 1143 | 1144 | :::{.content-left} 1145 | 1146 | # ”main 函数“ 1147 | 1148 | --- 1149 | 1150 | - 防止导入时运行代码{.tobuild.fadeIn} 1151 | - 只允许直接运行脚本时运行{.tobuild.fadeIn} 1152 | - 通过判断 \_\_name\_\_{.tobuild.fadeIn} 1153 | - 如果是直接运行,则其等于字符串 \_\_main\_\_ 1154 | - 如果是被导入的,则其等于模块名 1155 | 1156 | ::: 1157 | 1158 | :::{.content-right} 1159 | ```python 1160 | # code.py 1161 | ... 1162 | if __name__ == "__main__": 1163 | print("hello") 1164 | else: 1165 | print(__name__) 1166 | ``` 1167 | ```python 1168 | import code # code 1169 | ``` 1170 | ```bash 1171 | $ python code.py # hello 1172 | ``` 1173 | 1174 | 1175 | 1176 | # 内部模块 1177 | 1178 | --- 1179 | 1180 | * python 自带了很多实用的模块(标准库) 1181 | 1182 | - os、sys:系统操作 1183 | - math:数学运算 1184 | - re:正则表达式 1185 | - datetime:日期与时间 1186 | - subprocess:子进程管理 1187 | - argparse:命令行参数解析 1188 | - logging:日志记录 1189 | - hashlib:哈希计算 1190 | - random:随机数 1191 | - csv、json:数据格式解析 1192 | - collections:更多类型 1193 | - ... 1194 | {.text-cols.build} 1195 | 1196 | * 看文档:[docs.python.org/zh-cn/3/library](https://docs.python.org/zh-cn/3/library/index.html) {.tobuild.fadeInUp} 1197 | 1198 | 1199 | 1200 | # 外部模块安装 1201 | 1202 | --- 1203 | 1204 | - pypi.org 上有极多别人写好了可以用的模块{.tobuild.fadeIn} 1205 | - numpy 矩阵等科学计算、scipy 科学计算、matplotlib 作图…… 1206 | - 使用 pip 安装(pip / python -m pip){.tobuild.pulse} 1207 | - pip install pkg_name{.tobuild.fadeInUp} 1208 | - pip install pkg_name=... 指定版本{.tobuild.fadeInUp} 1209 | - pip install -r requirements.txt 安装 txt 文件中的所有包{.tobuild.fadeInUp} 1210 | - pip install ... -i [https\://pypi.tuna.tsinghua.edu.cn/simple](https://pypi.tuna.tsinghua.edu.cn/simple) 换源{.tobuild.fadeInUp} 1211 | - pip list、pip show 命令查看安装的所有包/某个包的信息{.tobuild.fadeInUp} 1212 | - pip uninstall pkg_name 卸载包{.tobuild.fadeInUp} 1213 | - pip 安装本地模块{.tobuild.pulse} 1214 | - 目录下需要包含 setup.py / pyproject.toml{.tobuild.fadeInUp} 1215 | - pip install . 安装本地模块(复制到 site-packages 中){.tobuild.fadeInUp} 1216 | - pip install -e . 可修改形式安装本地模块(在当前位置,可以直接修改代码){.tobuild.fadeInUp} 1217 | 1218 | 1219 | 1220 | :::{.content-left} 1221 | 1222 | # 文档字符串 1223 | 1224 | --- 1225 | 1226 | - 模块开头的三引号字符串{.tobuild.fadeIn} 1227 | - 类、函数定义下面的三引号字符串{.tobuild.fadeIn} 1228 | - help(...) 的时候可以显示{.tobuild.fadeIn} 1229 | - obj.\_\_doc\_\_ 表示这串字符串{.tobuild.fadeIn} 1230 | - 编辑器用来提示{.tobuild.fadeIn} 1231 | - 一些文档生成工具(sphinx 等)从中获取文档{.tobuild.fadeIn} 1232 | 1233 | ::: 1234 | 1235 | :::{.content-right} 1236 | ```python 1237 | """ 1238 | docstring for module 1239 | """ 1240 | 1241 | def func(...): 1242 | """docstring for function""" 1243 | ... 1244 | 1245 | class A(): 1246 | """docstring for class""" 1247 | def __init__(self, ...): 1248 | """docstring for method""" 1249 | ... 1250 | ``` 1251 | 1252 | 1253 | 1254 | # 代码规范 1255 | 1256 | --- 1257 | 1258 | - PEP:Python Enhancement Proposals:[peps.python.org](https://peps.python.org) {.tobuild.fadeIn} 1259 | - PEP 8 规范,给出了推荐使用的 python 代码风格规范{.tobuild.fadeIn} 1260 | - [peps.python.org/pep-0008](https://peps.python.org/pep-0008/) 1261 | - [pep8.org](https://pep8.org/) 1262 | - 更细致的代码风格{.tobuild.fadeIn} 1263 | - black [github.com/psf/black](https://github.com/psf/black) {.tobuild.fadeInUp} 1264 | - flake8 [flake8.pycqa.org](https://flake8.pycqa.org/en/latest/) {.tobuild.fadeInUp} 1265 | - ...{.tobuild.fadeInUp} 1266 | 1267 | 1268 | 1269 | # 更多? 1270 | 1271 | --- 1272 | 1273 | - 加群:[995146332](https://jq.qq.com/?_wv=1027&k=kaVgMwA3) {.tobuild.pulse} 1274 | - 基础{.tobuild.pulse} 1275 | - 《Python 编程:从入门到实践》[ISBN 978-7-115-54608-1](https://www.ituring.com.cn/book/2784) {.tobuild.fadeInUp} 1276 | - Python 3 菜鸟教程 [runoob.com/python3/python3-tutorial.html](https://www.runoob.com/python3/python3-tutorial.html) {.tobuild.fadeInUp} 1277 | - Python 官方文档 tutorial [docs.python.org/3/tutorial](https://docs.python.org/3/tutorial/index.html) {.tobuild.fadeInUp} 1278 | - 中国大学 mooc - 浙江大学 [Python 程序设计](https://www.icourse163.org/course/ZJU-1206456840) {.tobuild.fadeInUp} 1279 | - 进阶{.tobuild.pulse} 1280 | - 《流畅的 Python》[ISBN 978-7-115-45415-7](https://www.ituring.com.cn/book/1564) {.tobuild.fadeInUp} 1281 | - Python 官方文档 [docs.python.org/3](https://docs.python.org/3/) {.tobuild.fadeInUp} 1282 | - 学一些实用的第三方库,看文档{.tobuild.fadeInUp} 1283 | - PEP [peps.python.org](https://peps.python.org/pep-0000/)(注意分清有没有实施){.tobuild.fadeInUp} 1284 | - GitHub 找项目读{.tobuild.fadeInUp} 1285 | 1286 | 1287 | 1288 | # 结{.text-shadow} 1289 | 1290 | --- 1291 | 1292 | Thanks for watching{.text-landing} -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/PythonLecture/888153c7012ed202b828900229a67cd1fc057a3b/public/favicon.png -------------------------------------------------------------------------------- /public/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "JetBrains Mono", "LXGW WenKai Screen"; 3 | font-size: 2.3rem; 4 | } 5 | .text-intro { 6 | font-size: 2.7rem; 7 | } 8 | .flexblock li h2, h2 { 9 | font-size: 2.8rem; 10 | } 11 | h1 { 12 | font-size: 6.0rem; 13 | } 14 | pre[class*=language-], code[class*=language-], pre, code { 15 | font-family: "JetBrains Mono", "LXGW WenKai Screen"; 16 | font-size: 2.3rem; 17 | font-variant-ligatures: none; 18 | } 19 | code[class*=small-code] { 20 | font-size: 2rem; 21 | } 22 | h1.small-h1 { 23 | font-size: 5.5rem; 24 | } 25 | .big-title { 26 | font-size: 3.5em; 27 | } 28 | .pink-button, .pink-button:hover { 29 | border-color: #FF94B1; 30 | } 31 | 32 | 33 | /****************** dark theme ******************/ 34 | /* body { 35 | background-color: #1D1D1D; 36 | color: #FFFFFFE6; 37 | } 38 | hr { 39 | background-image: radial-gradient(at center center, rgba(220, 228, 255, 0.64) 0px, rgb(29, 29, 29) 75%); 40 | } 41 | .bg-white { 42 | background-color: #333333; 43 | } 44 | a { 45 | color: #4799FF; 46 | } 47 | code, [class*='bg-'] pre { 48 | background-color: #1D1D1D; 49 | } 50 | .language-css .token.string, .style .token.string, .token.entity, .token.operator, .token.url { 51 | background: none; 52 | } 53 | .text-shadow { 54 | text-shadow: 0 0 40px rgb(204 204 204 / 50%); 55 | } */ -------------------------------------------------------------------------------- /slide_dark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/PythonLecture/888153c7012ed202b828900229a67cd1fc057a3b/slide_dark.pdf -------------------------------------------------------------------------------- /slide_light.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/PythonLecture/888153c7012ed202b828900229a67cd1fc057a3b/slide_light.pdf -------------------------------------------------------------------------------- /test.txt: -------------------------------------------------------------------------------- 1 | abcd 2 | aaaa 3 | cccc -------------------------------------------------------------------------------- /test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/PythonLecture/888153c7012ed202b828900229a67cd1fc057a3b/test.zip -------------------------------------------------------------------------------- /test2.txt: -------------------------------------------------------------------------------- 1 | abcdabcd --------------------------------------------------------------------------------