notepad++配置python环境
1. Notepad++ ->"运行"菜单->"运行"按钮
2. 在弹出的窗口内输入以下命令:
cmd /k python "$(FULL_CURRENT_PATH)" & ECHO. & PAUSE & EXIT
然后点击“保存”,随意取一个名字,比如“RunPython”,为方便,配置一下快捷键(比如 Ctrl + F5),点OK即可。之后运行Python文件只要按配置的快捷键或者在运行菜单上点“RunPython”即可。
注意不要跟已有的快捷键冲突。查看已有的快捷键,可以点击"运行"菜单->"管理快捷键"按钮 查看
pycharm快捷键
Ctrl + / 行注释
Ctrl + Alt + L 代码格式化Ctrl + Q 快速查看文档Ctrl + Alt + M提取方法Ctrl + Alt + V提取属性Ctrl + Alt + F提取字段Ctrl + Alt + C提取常量Ctrl + Alt + P提取参数
Python打包成exe工具
推荐使用pyinstaller
1.py2exe
官方主页:
但是py2exe只支持到python3.4
2.pyinstaller
官方主页: 。pyinstaller是一个多平台的Python程序打包为exe的免费工具。在Windows中,pyinstaller依赖PyWin32,如果在安装pyinstaller时使用的是pip会自动pypwin32,否则需手动安装pip install pywin32
Pyinstaller如果没有加参数,就会打包成散包。具体参数如下:
参数 | 定义 |
-F | 指定打包后只生成一个exe格式的文件 |
-D | –onedir 创建一个目录,包含exe文件,但会依赖很多文件(默认选项) |
-c | –console, –nowindowed 使用控制台,无界面(默认) |
-w | –windowed, –noconsole 使用窗口,无控制台 |
-p | 添加搜索路径,让其找到对应的库。 |
-i | 改变生成程序的icon图标 |
pyinstaller -F xxxx.py 生成一个文件
pyinstaller -F -i ico图片路径 py文件路径
3.cx_freeze
官方主页:
去掉console窗口,添加选项--base-name=,可选值为[Console、Win32GUI、Win32Service、ConsoleKeepPath]
python pip源
pipy国内镜像目前有:
豆瓣
华中理工大学
山东理工大学
中国科学技术大学
手动指定源:
在pip后面跟-i 来指定源,比如用豆瓣的源来安装web.py框架:
pip install web.py -i
注意后面要有/simple目录!!!
Python语法
1、万物皆对象
在python中任何东西都是对像,数据类型,模块,函数等都是是一个对象,都有自己的属性(attribute)和方法(property 属性函数)可以使用dir()查询,函数作为一个对象,它还可以赋值给其它对象名,或者作为参数传递。
2、编码
所有的 Python 脚本文件都应在文件头标上
# -*- coding:utf-8 -*-
用于设置编辑器,默认保存为 utf-8 格式。coding后用冒号和等号都可以
在Linux中# -*- coding:utf-8 -*-必须放在文档的第二行,也就是#!/usr/bin/env python的下一行,而且行头不能有空格。
默认情况下,Python 3源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 也可以为源码文件指定不同的编码,在文件头部加上:
# coding=gbk
3、 大小写
Python对大小写十分敏感,如果大小写错误,会报错。
4、注释
Python 的注释分为两种,
一种是由 # 开头的“
多行注释用三个单引号(''')或者三个双引号(""")将注释括起来。
5、 缩进
Python 依赖缩进来确定代码块的层次,行首空白符主要有两种:tab 和 空格,但严禁两者混用。如果使用 tab 缩进,设定tab 为 4 个空格。
6、空格
空格在 Python 代码中是有意义的,因为 Python 的语法依赖于缩进,在行首的空格称为前导空格。非前导空格在 Python 代码中没有意义,但适当地加入非前导空格可以增进代码的可读性。
1)在二元算术、逻辑运算符前后加空格:如
a = b + c;
2) 在一元前缀运算符后不加空格,如
if !flg: pass;
3) 括号(含圆括号、方括号和花括号)前后不加空格,如:
do_something(arg1, arg2)
4)不要在逗号、分号、冒号前面加空格,但应该在它们后面加(除了在行尾)
7、空行
适当的空行有利于增加代码的可读性,加空行可以参考如下几个准则:
1) 在类、函数的定义间加空行; 2) 在 import 不同种类的模块间加空行; 3) 在函数中的逻辑段落间加空行,即把相关的代码紧凑写在一起,作为一个逻辑段落,段落间以空行分隔;
8、断行
Python会将圆括号、中括号、花括号中的行隐式的连接起来,如需要,你可以在表达式外围增加一对额外的圆括号。
如print (keyword.kwlist) 和下面的效果是一样的
print (keyword
.kwlist)
在Python中,默认以换行为新的一行,若想在一行输入多句语句,一定要加‘;’,否则报错
当语句以‘:’结尾时,缩进语句视为代码块。
10、关键字:keywords
关键字其实就是python内部已经使用了的标识符,如果使用这些关键字,将会覆盖python内置的功能,可能会导致无法预知的错误。关键字必须准确拼写,因为python是区分大小写的。
and | del | from | not | while |
as | elif | global | or | with |
assert | else | if | pass | yield |
break | except | import | |
|
class | exec | in | raise |
|
continue | finally | is | return |
|
def | for | lambda | try |
|
Python的标准库提供了一个keyword module,可以输出当前版本的所有关键字:
>>> import keyword
>>> keyword.kwlist
11、命名
一致的命名可以给开发人员减少许多麻烦,而恰如其分的命名则可以大幅提高代码的可读性,降低维护成本。
12、常量
常量名所有字母大写,由下划线连接各个单词,如
WHITE = 0XFFFFFF
THIS_IS_A_CONSTANT = 1
13、变量
Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建
Python可以同时为多个变量赋值,如a, b = 1, 2。
变量名全部小写,由下划线连接各个单词,如
color = WHITE
this_is_a_variable = 1
私有类成员使用单一下划线前缀标识,多定义公开成员,少定义私有成员。
变量名不应带有类型信息,因为 Python 是动态类型语言。如 iValue、names_list、dict_obj 等都是不好的命名。
14、 函数
函数名的命名规则与变量名相同。
15、类
对类名使用大写字母开头的单词(如CapWords, 即Pascal风格),不使用下划线连接单词。如:
class ThisIsAClass(object):pass
16、模块
模块名全部小写,对于包内使用的模块,可以加一个下划线前缀,如
module.py
_internal_module.py
在程序的开发过程中,随着程序代码越写越多,在一个文件里代码会越来越不容易维护。为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少。在Python中一个.py文件就称之为一个模块(Module)。模块也被叫做库。
模块的分类
内置模块 :Python官方提供的一些模块功能,比如:random,json,string,base64,pickle,sys,os等
自定义模块:根据自己需求编写的一些.py文件或一类模块以及包。
第三方模块:非Python本身自带的一些模块甚至框架。比如:request,Image,Django,Scrapy等。
17、包
模块用来从逻辑上组织Python代码,是.py结尾的python文件。包用来从逻辑上组织模块的,包和一般的文件夹没什么区别,关键是包文件夹下必须包含一个__init__.py,表明这是一个包。包的命名规范与模块相同。
函数---->类---->模块(.py文件)---->包
18、模块的安装
方法1:单文件模块
直接把文件拷贝到 $python_dir/Lib
方法2:多文件模块,带setup.py
下载模块包进行解压,进入模块文件夹,执行:
python setup.py installsetup.py文件的编写
setup.py中主要执行一个 setup函数,该函数中大部分是描述性东西,最主要的是packages参数,列出所有的package,可以用自带的find_packages来动态获取package。setup.py文件:
from setuptools import setup, find_packages
setup( name = " mytest " , version = " 0.10 " , description = " My test module " , author = " Robin Hood " , url = " http://www.xxx.com " , license = " LGPL " , packages = find_packages(), scripts = [ " scripts/test.py " ], )mytest.py
import sys
def get(): return sys.pathscripts/test.py
import os
print os.environ.keys()setup中的scripts表示将该文件放到 Python的Scripts目录下。
方法3:pip 方式
安裝:pip install PackageName
查看已安装的某包:pip3 show --files SomePackage
列出已安装的包 pip3 freeze
列出已安装的包 pip3 list
搜索:pip3 search PackageName
检测更新:pip3 list --outdated
更新:pip3 install -U PackageName
移除:pip3 uninstall PackageName
导入模块
python调用模块的步骤:
1. 检索可用路径(这个可用路径类似于linux下的PATH全局变量)
2. 根据路径的优先级来查找模块,其中当前路径的优先级最高
3. 从可用路径中查找模块
由此可知要使我们的模块可以被python检索到,模块就必须放在可用路径内
1、\lib\site-packages为标准化的第三方模块存放路径。可将将自己写的exp.py 文件放到sys.path列表中的目录里(如site-packages目录),使用时采用 import exp 导入。
2、在sys.path列表中添加新的路径。如果想要自己定义模块的存放位置,可以通过sys.path.append('模块路径')来添加自己模块的路径。
3、创建一个文件并命名为mytest.py ,然后新建一个文件夹,命名myModule,将mytest.py放到文件夹中,并将文件夹放到自己的某个路径下。 复制刚刚myModule文件夹的路径,例如D:\Develop\Python\myModule,将其写入到一个新的txt文件中并将这个txt命名为myModule.pth。 最后将这个myModule.pth文件放到python的安装路径→Lib\site-packages的文件夹下。这样,Python 在遍历已知的库文件目录过程中,如果见到一个 .pth 文件,就会将文件中所记录的路径加入到 sys.path 设置中,这样 .pth 文件说指明的package也就可以被Python运行环境顺利找到, 我们就可以像使用内置模块一样引入自定义模块了。使用时直接import mytest即可
import module 导入模块,推荐import来去导入因为这样可以使你的程序更加易读,也可以避免名称的冲突
import module_name,module2_name 导入多个模块
from module import * 从模块导入所有方法
如果采用from module import *,则可在代码中直接使用方法名,这种导入方法有弊端,比如有两个模块 a,b 两个模块中都有一个hello()方法,这时就会方法冲突。解决办法是方法前面加上模块名。
如果采用import module,则在代码中必须写成module.function的形式
from packs import hello 从包中导入模块
下面将具体介绍几种常用情况:
(1)主程序与模块程序在同一目录下:如下面程序结构:-- src |-- mod1.py |-- test1.py 若在程序test1.py中导入模块mod1, 则直接使用import mod1或from mod1 import *;(2)主程序所在目录是模块所在目录的父(或祖辈)目录如下面程序结构:-- src |-- mod1.py |-- mod2 |-- mod2.py |-- test1.py 若在程序test1.py中导入模块mod2, 需要在mod2文件夹中建立空文件__init__.py文件(也可以在该文件中自定义输出模块接口); 然后使用 from mod2.mod2 import * 或import mod2.mod2.(3)主程序导入上层目录中模块或其他目录(平级)下的模块如下面程序结构:-- src |-- mod1.py |-- mod2 |-- mod2.py |-- sub |-- test2.py |-- test1.py 若在程序test2.py中导入模块mod1和mod2。首先需要在mod2下建立__init__.py文件(同(2)),src下不必建立该文件。
标识符:Identifiers
标识符必须以字母(大小写均可)或者"_"开头。标识符没有长度限制 ,区分大小写。标识符的作用是作为变量,函数名,类名,方法名等
_xxx 和__xxx这样的函数或变量是非公开的(private),不应该被直接引用(可以以被引用,但不建议这样做)
_xxx意味着该方法或属性不应该去调用,不会被 from module import * 导入。__xxx作用是用来避免子类覆盖其内容,__xxx的方法不能被重写,它只允许在该类的内部中使用。__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如__author__,__name__就是特殊变量,__xxx__的方法是特殊方法,可以在外部直接访问。我们自己的变量一般不要用这种变
__file__ 获取当前运行的py文件所在的目录
__doc__ 函数、或者文档的注释__author__
__package__ 输出对应函数属于哪个包 . admin.__package____name__若是该文件被执行则__name__ 就等于“__main__”, 若是导入该文件则表示获取函数的名称。经常使用if __name__ == '__main__',保证你写包既可以import又可以独立运行,否则一import程序就开始运行了。
查看用户安装的模块: pip list
查看已安装的模块: help('modules') import sys;sys.modules.keys() 查看系统内置内的变量(属性)和 函数(方法): dir(__builtins__) import builtins dir(builtins) 查看当前系统import了那些模块:dir()查看某模块说明: help("XXX")
查看某模块的某个方法/属性: help(module.属性/方法)查看某模块包含的变量(属性)和函数(方法): dir(XXX)查看内置全局变量: print(vars())
查看所有的关键字: help("keywords")
a=[1,2,3]
print(dir(a)) #查看对象所有属性print(help(a)) #查看对象所有属性的详细说明print(help(a.pop)) #查看对象指定的属性
python2和Python3共存
对于Ubuntu 16.04 LTS版本来说,已默认同时安装了Python2(2.7.12)和Python3(3.5.2),默认的python版本是2.7.12。如果想调用python2就用python2。如果想调用python3,就用python3.
对于Windows,不论python2还是python3,python可执行文件都叫python.exe,在cmd下输入python得到的版本号取决于环境变量里哪个版本的python路径更靠前,比如环境变量里的顺序是这样的:那么cmd下的python版本就是2.7。
这就带来一个问题了,如果你一会想用python2运行一个脚本,一会你又想用python3运行另一个脚本,来回改环境变量显然很麻烦。有一个比较好的解决办法,是借用py来调用不同版本的Python。py -2调用python2,py -3调用的是python3.
当python脚本需要python2运行时,只需在脚本前加上#! python2,然后运行py xxx.py即可。
当python脚本需要python3运行时,只需在脚本前加上#! python3,然后运行py xxx.py即可。
当需要python2的pip时,只需py -2 -m pip install xxx
当需要python3的pip时,只需py -3 -m pip install xxx
ASCII编码 是对应英文字符与二进制数字之间的关系;ASCII一共规定了128种,如大写字母A是65,即01000001;可见一字母一字节;
GB2312编码 简体中文常见的编码,两个字节代表一个中文汉字 ,理论上256*256个编码,即可表示65536种中文字;
各国编码不同,为了各国能扩平台进行文本的转换与处理,Unicode就被作为统一码或者单一码。Unicode编码通常是两个字节,unicode与ASCII编码的区别,在于unicode在ASCII编码前加了一个0,即字母A的ASCII编码为01000001,unicode编码即为0000000001000001;但英文字母其实只用一个字节就够了,unicode编码写英文时多了一个字节,浪费存储空间。因而unicode开发了通用转换格式(Unicode Transformation Format(UTF)),常见的有utf-8或者utf-16;
python字符编码
(1)encode的作用是,将unicode对象编码成其他编码的字符串,str.encode('utf-8'),编码成UTF-8;(2)decode的作用是将其他编码的字符串转换成Unicode编码,str.decode('UTF-8');作为统一标准,unicode不能再被解码,如果UTF-8想转至其他非unicode,则必须先decode 到unicode,在encode到其他非unicode的编码。 (2)Python中的字典能够被序列化到json文件中存入jsonwith open("anjuke_salehouse.json","w",encoding='utf-8') as f:
json.dump(all_house,f,ensure_ascii=False,sort_keys=True, indent=4); print(u'加载入文件完成...');json.dump将一个对象序列化存入文件。dump()的第一个参数是要序列化的对象,第二个参数是打开的文件句柄,注意文件打开open()时加上以UTF-8编码打开,在dump()的时候也加上ensure_ascii=False,不然会变成ascii码写到json文件中
json.dumps() 是将一个Python数据结构转换为一个JSON编码的字符串,{"name": "xiaoming"}。而dumps(str)无需写入文件,将python字符串转成json字典。
json.loads() 是将一个JSON编码的字符串(字典形式)转换为一个Python数据结构,{u'name': u'xiaoming'}
dumps转化后键与值都变成了双引号,而在loads后变成python变量时,元素都变成了单引号,并且字符串前加多了个u。
一般要求当要字符串通过loads转为python数据类型时,得外层用单引号,里面元素key和value用双引号。
错误
ptyhon的错误其实也是 class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。
BaseException 所有异常的基类
+-- SystemExit 解释器请求退出
+-- KeyboardInterrupt 用户中断执行(通常是输入^C)
+-- GeneratorExit 生成器(generator)发生异常来通知退出
+-- Exception 常规错误的基类
+-- StopIteration 迭代器没有更多的值
+-- StopAsyncIteration
+-- ArithmeticError 所有数值计算错误的基类
| +-- FloatingPointError 浮点计算错误
| +-- OverflowError 数值运算超出最大限制
| +-- ZeroDivisionError 除(或取模)零 (所有数据类型)
+-- AssertionError 断言语句失败
+-- AttributeError 对象没有这个属性
+-- BufferError
+-- EOFError 没有内建输入,到达EOF 标记
+-- ImportError 导入模块/对象失败
| +-- ModuleNotFoundError
+-- LookupError 无效数据查询的基类
| +-- IndexError 序列中没有此索引(index)
| +-- KeyError 映射中没有这个键
+-- MemoryError 内存溢出错误(对于Python 解释器不是致命的)
+-- NameError 未声明/初始化对象 (没有属性)
| +-- UnboundLocalError 访问未初始化的本地变量
+-- OSError 输入/输出操作失败
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
+-- RuntimeError 一般的运行时错误
| +-- NotImplementedError 尚未实现的方法
| +-- RecursionError
+-- SyntaxError Python语法错误
| +-- IndentationError 缩进错误
| +-- TabError Tab 和空格混用
+-- SystemError 一般的解释器系统错误
+-- TypeError 对类型无效的操作
+-- ValueError 传入无效的参数
| +-- UnicodeError Unicode 相关的错误
| +-- UnicodeDecodeError Unicode 解码时的错误
| +-- UnicodeEncodeError Unicode 编码时错误
| +-- UnicodeTranslateError Unicode 转换时错误
+-- Warning 警告的基类
+-- DeprecationWarning 关于被弃用的特征的警告
+-- PendingDeprecationWarning 关于特性将会被废弃的警告
+-- RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
+-- SyntaxWarning 可疑的语法的警告
+-- UserWarning 用户代码生成的警告
+-- FutureWarning 关于构造将来语义会有改变的警告
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
1 python始终记录变量最新值。 变量名推荐小写。
Python 格式化输出
在进行格式化输出时,%r 与 %s 的区别就好比 repr() 函数处理对象与 str() 函数处理对象的差别。
- %s -> str(),比较智能;
- %r -> repr(),处理较为简单和直接; 处理一些简单对象时,二者几乎没有差别.
random.shuffle 打乱序列
>>> import random>>> a=range(10)>>> random.shuffle(a)>>> a [1, 0, 8, 5, 6, 7, 9, 3, 2, 4] >>> random.shuffle(a) >>> a [7, 5, 6, 2, 1, 8, 9, 0, 3, 4]
Python内置序列类型的主要分类:
按可存放的元素类型分为:容器序列和扁平序列
- 容器序列,就是什么都能作为元素往里放,包括另一个序列。需要注意的是,如果元素是序列类型,那么存放的往往是引用,需要小心。常见的容器序列包括:list,tuple,array.array,collections.deque等。
- 扁平序列,存放的都是原子级元素,此时存放的是值而不会是引用。常见的扁平序列包括:str,bytes,bytearray, memoryview, array.array等。
按序列能否被修改分为:可变序列与不可变序列
- 可变序列:可以进行增、删、改等操作的序列,包括list, bytearray, array.array, collections.deque, memoryview等。
- 不可变序列:不可进行上述操作的序列,包括tuple, str, bytes等。
字典的变种
标准库里collections模块中提供了很多与字典类型相似的变种。
OrderDict: 这个类型在添加键的时候,会保存顺序,因此键的迭代顺序总是一致的
ChainMap: 该类型可以容纳数个不同的映射对像,在进行键的查找时,这些对象会被当做一个整体逐个查找,直到键被找到为止
Counter: 这个映射类型会给键准备一个整数技术器,每次更行一个键的时候都会增加这个计数器,所以这个类型可以用来给散列表对象计数,或者当成多重集来用。
UserDict: 这个类其实就是把标准的dict用Python又写了一遍。一般用来给程序员想要通过继承dict创建自己的dict时,代替dict使用的。主要是因为直接继承原生dict会出现bug。
defaultdict:处理找不到的键的一个选择
当某个键不在映射里, 我们也希望也能得到一个默认值. 这就是 defaultdict , 它是 dict 的子类, 并实现了 missing 方法.
第一种:class内部def函数与def函数之间的调用
test_getIdentify 函数调用test_getLastuser函数的返回值,只要在test_getIdentify 函数内写上self.test_getLastuser()即可
class testlogin(unittest.TestCase):
def test_getIdentify(self):'''先调用上一次用户登录的信息,返回展示在页面上'''key=self.test_getLastuser()data={"username":key}url="http://10.17.17.31:8080/LandTaxSys/user/getIdentity"headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}r=requests.get(url,params=data,headers=headers)print(r.text)return r.textdef test_getLastuser(self):'''获取上一次用户登录的用户名'''url="http://10.17.17.31:8080/LandTaxSys/operatelog/getLastUser"r=requests.get(url)return r.text第二种 不同文件夹下的py之间的函数调用,如下图
第三种:Class之间函数的调用关系
假设有Class A 和 Class B两个类,Class A中定义了a(),Class B中定义了b().现在我想在Class B中调用 Class A中的函数a()。此处介绍三种调用方法:
方法一:
在Class B中所定义的fuction()中声明Class A的对象a,然后用对象a来调用Class A的函数a().
最后在main中声明Class B的对象b,让b调用该类中的fuction().
[python] view plain copy#!/usr/bin/env python # -*- coding: utf-8 -*- class A(): def __init__(self,parent): self.parent = parent def a(self): print 'Class A' class B(): def fuction(self): a = A(None) a.a() if __name__ == '__main__': b = B() b.fuction()
方法二:
在Class B的__init__()中将Class A和Class B产生关联,具体方法如下code。
首先在main中声明Class A的对象a,然后将对象a传入到Class B的__init__(self,object)中,这样self.object就指向Class A。
就可以调用Class A中的函数了。[python] view plain copy
#!/usr/bin/env python # -*- coding: utf-8 -*- class A(): def __init__(self,parent): self.parent = parent def a(self): print "Class A" class B(object): def __init__(self,object): self.object = object self.object.a() def b(self): print "Class B" if __name__ == '__main__': a = A(None) b = B(a) b.b()方法三:
直接在Class B中声明Class A的对象,该对象是Class B的self.A_object。
[python] view plain copy
#!/usr/bin/env python # -*- coding: utf-8 -*- class A(): def a(self): print "Class A" class B(object): def __init__(self): self.A_object = A() self.A_object.a() def b(self): print "Class B" if __name__ == '__main__': b = B() b.b()
类的方法的调用
1.类的内部调用:self.<方法名>(参数列表)。2.在类的外部调用:<实例名>.<方法名>(参数列表)。注意:以上两种调用方法中,提供的参数列表中都不用包括self。
在class外部定义的可执行函数,都是函数。
class Apple:
def fun1(self): #普通方法
return 'normal'
@staticmethod #静态方法
def fun2():
return 'staticmethod'
@classmethod #类方法
def fun3(cls):
return 'classmethod'
print('_________________________________________________')print(Apple.fun1)print (Apple.fun2)print (Apple.fun3)print('_________________________________________________')
apple = Apple()print (apple.fun1)print (apple.fun2)print (apple.fun3)print('_________________________________________________') 结果如下:_________________________________________________<function Apple.fun1 at 0x000000000285EA60><function Apple.fun2 at 0x000000000285EB70><bound method type.fun3 of <class '__main__.Apple'>>_________________________________________________<bound method Apple.fun1 of <__main__.Apple object at 0x0000000002A65CC0>><function Apple.fun2 at 0x000000000285EB70><bound method type.fun3 of <class '__main__.Apple'>>_________________________________________________ 普通方法,类对象调用func是方法,类调用func是函数,并且是自己传递参数123!静态方法,类或实例调用都是函数。类方法,类或实例调用都是方法与类和实例无绑定关系的function都属于函数(function);
与类和实例有绑定关系的function都属于方法(method)。最大的区别是参数的传递参数,方法是自动传参self,函数是主动传参
help() 帮助id( ) 查询内存地址__init__() 类初始化方法__del__() 类析构方法@classmethod 装饰为类方法@staticmethod 静态方法(类内普通函数)inheritance 继承(单继承)multiple inheritance 多继承derived 派生base class 基类super class 超类father class 父类derived class 派生类child class 子类
字符串 (str) 是不可变序列 “” 列表 [list] 是可变的序列 [ ] (索引、切片、索引切片赋值)元组 (tuple) 是不可变的序列 ( ) (索引、切片 不可变 不能赋值)字典 {dict} 是可变无序的容器 { } (键索引,键赋值 没有创建 有则修改)集合 {set} 是可变的容器 { } (元素无法重复、索引切片)固定集合 {frozenset} 不可变 无序 唯一元素的集合 { } (索引切片)字节串 “bytes” 是不可变的字节序列 “ ” (索引切片)字节数组 (bytearray) 是 可变的字节序列 () (索引 切片 赋值)
Python3 中常用字符串方法(method)
字符串的方法调用语法:对象.方法名(方法传参)
常用字符串方法:(假设字符串变量名为S)
方法 | 说明 |
S.isdigit() | 判断字符串中的字符是否全为数字 |
S.isalpha() | 判断字符串是否全为英文字母 |
S.islower() | 判断字符串所有字符是否全为小写英文字母 |
S.isupper() | 判断字符串所有字符是否全为大写英文字母 |
S.isspace() | 判断字符串是否全为空白字符 |
S.center(width[,fill]) | 将原字符串居中,左右默认填充空格 width:所居中字符串的长度 fill:默认填充空格 |
S.count(sub[, start[,end]]) | 获取一个字符串中子串的个数 sub:所要获取的字符串 start:起始位置 end:结束位置 |
S.find(sub[, start[,end]]) | 获取字符串中子串sub的索引,失败返回-1 start:起始位置 end:结束位置 |
S.strip() | 返回去掉左右空白字符的字符串 |
S.lstrip() | 返回去掉左侧空白字符的字符串 |
S.rstrip() | 返回去掉右侧空白字符的字符串 |
S.upper() | 生成将英文转换为大写的字符串 |
S.lower() | 生成将英文转换为小写的字符串 |
S.replace(old, new[, count]) | 将原字符串的old用new代替,生成一个新的字符串 count:更换的次数 |
S.startswith(prefix[, start[, end]]) | 返回S是否是以prefix开头,如果以prefix开头返回True,否则返回False, |
S.endswith(suffix[, start[, end]]) | 返回S是否是以suffix结尾,如果以suffix结尾返回True,否则返回False |
以下是不常用的 |
|
S.title() | 生成每个英文单词的首字母大写字符串 |
S.isnumeric() | 判断字符串是否全为数字字符 |
Python3中常用的列表方法(method)
方法 | 意义 |
L.index(v [, begin[, end]]) | 返回对应元素的索引下标, begin为开始索引,end为结束索引,当 value 不存在时触发ValueError错误 |
L.insert(index, obj) | 将某个元素插放到列表中指定的位置 |
L.count(x) | 返回列表中元素的个数 |
L.remove(x) | 从列表中删除第一次出现在列表中的值 |
L.copy() | 复制此列表(只复制一层,不会复制深层对象) |
L.append(x) | 向列表中追加单个元素 |
L.extend(lst) | 向列表追加另一个列表 |
L.clear() | 清空列表,等同于 L[:] = [] |
L.sort(reverse=False) | 将列表中的元素进行排序,默认顺序按值的小到大的顺序排列 |
L.reverse() | 列表的反转,用来改变原列表的先后顺序 |
L.pop([index]) | 删除索引对应的元素,如果不加索引,默认删除最后元素,同时返回删除元素的引用关系 |
字典的方法
函数 | 说明 |
D代表字典对象 |
|
D.clear() | 清空字典 |
D.pop(key) | 移除键,同时返回此键所对应的值 |
D.copy() | 返回字典D的副本,只复制一层(浅拷贝) |
D.update(D2) | 将字典 D2 合并到D中,如果键相同,则此键的值取D2的值作为新值 |
D.get(key, default) | 返回键key所对应的值,如果没有此键,则返回default |
|
|
D.keys() | 返回可迭代的 dict_keys 集合对象 |
D.values() | 返回可迭代的 dict_values 值对象 |
D.items() | 返回可迭代的 dict_items 对象 |
Python3 集合的方法
方法 | 意义 |
S.add(e) | 在集合中添加一个新的元素e;如果元素已经存在,则不添加 |
S.remove(e) | 从集合中删除一个元素,如果元素不存在于集合中,则会产生一个KeyError错误 |
S.discard(e) | 从集合S中移除一个元素e,在元素e不存在时什么都不做; |
S.clear() | 清空集合内的所有元素 |
S.copy() | 将集合进行一次浅拷贝 |
S.pop() | 从集合S中删除一个随机元素;如果此集合为空,则引发KeyError异常 |
S.update(s2) | 用 S与s2得到的全集更新变量S |
|
|
S.difference(s2) | 用S - s2 运算,返回存在于在S中,但不在s2中的所有元素的集合 |
S.difference_update(s2) | 等同于 S = S - s2 |
S.intersection(s2) | 等同于 S & s2 |
S.intersection_update(s2) | 等同于S = S & s2 |
S.isdisjoint(s2) | 如果S与s2交集为空返回True,非空则返回False |
S.issubset(s2) | 如果S与s2交集为非空返回True,空则返回False |
S.issuperset(...) | 如果S为s2的子集返回True,否则返回False |
S.symmetric_difference(s2) | 返回对称补集,等同于 S ^ s2 |
S.symmetric_difference_update(s2) | 用 S 与 s2 的对称补集更新 S |
S.union(s2) | 生成 S 与 s2的全集 |
Python运算符优先级
运算符 | 描述 |
|
|
(), [], {key: value}, {} | 元组表达式、列表表达式、字典表达式、集合表达式 |
x[index], x[index:index], x(arguments...), x.attribute | 索引,切片, 函数调用,属性引用 |
|
|
** | 指数 (最高优先级) |
~, +, - | 按位翻转, 正号,负号 |
*, /, %, // | 乘,除,取模和地板除 |
+, - | 加法, 减法 |
>>, << | 右移, 左移运算符 |
& | 位与(AND) |
^ | 位异或(XOR) |
| | 位或(OR) |
<=, <, >, >=, ==, !=, is, is not, in, not in | 比较,身份测试,成员资格测试 |
not | 布尔非 |
and | 布尔与 |
or | 布尔或 |
if - else | 条件表达式 |
lambda | lambda表达式 |
文件
mode 模式字符的含义
字符 | 含义 |
'r' | 以只读方式打开(默认) |
'w' | 以只写方式打开,删除原有文件内容(如果文件不存在,则创建该文件并以只写方式打开) |
'x' | 创建一个新文件, 并以写模式打开这个文件,如果文件存在则会产生"FileExistsError"错误 |
'a' | 以只写文件打开一个文件,如果有原文件则追加到文件末尾 |
'b' | 用二进制模式打开 |
't' | 文本文件模式打开 (默认) |
'+' | 为更新内容打开一个磁盘文件 (可读可写) |
缺省模式是 'rt'
'w+b' 可以实现二进制随机读写,当打开文件时,文件内容将被清零
'r+b' 以二进制读和更新模式打开文件,打开文件时不会清空文件内容
'r+' 以文本模式读和更新模式打开文件,打开文件时不会清空文件内容
python 文件常用方法:
方法 | 说明 |
F.close() | 关闭文件(关闭后文件不能再读写会发生ValueError错误) |
F.readline() | 读取一行数据, 如果到达文件尾则返回空行 |
F.readlines(max_chars=-1) | 返回每行字符串的列表,max_chars为最大字符(或字节)数 |
F.writelines(lines) | 将字符串的列表或字符串的列表中的内容写入文件 |
二进制文件操作方法 |
|
F.read(size=-1) | 从一个文件流中最多读取size个字符(文本文件)或字节(二进制文件),如果不给出参数,则默认读取文件中全部的内容并返回 |
F.write(text) | 写一个字符串到文件流中,返回写入的字符数(文本文件)或字节数(二进制文件) |
F.tell() | 返回当前文件流读写指针的绝对位置(字节为单位) |
F.seek(offset, whence=0) | 改变数据流读写指针的位置,返回新的绝对位置 |
F.flush() | 把写入文件对象的缓存内容写入到磁盘 |
|
|
F.readable() | 判断这个文件是否可读,可读返回True,否则返回False |
F.writable() | 判断这个文件是否可写,可写返回True,否则返回False |
F.seekable() | 返回这个文件对象是否支持随机定位 |
F.truncate(pos = None) | 剪掉 自pos位置之后的数据,返回新的文件长度 |
内建函数
数值对象的构造(创建)函数
函数 | 说明 |
float(obj) | 用字符串或数字转换为浮点数, 如果不给出参数,则返回0.0 |
int(x, base=10) int(x=0) | 用数字或字符串转换为整数,如果不给出参数,则返回0 |
complex(r=0.0, i=0.0) | 用数字创建一个复数(实部为r,虚部为i) |
bool(x) | 用x创建一个布尔值(True/False) |
预置(内建)的数值型函数
函数 | 说明 |
abs(x) | 取x的绝对值 |
round(number[, ndigits]) | 对数值进行四舍五入, ndigits是小数向右取整的位数, 负数表示向左取整 |
pow(x, y, z=None) | 相当于x ** y 或 x**y % z |
基本输入输出
基本输入 input
input('提示字符串') 返回输入的字符串(仅Python3,'提示字符串' 可以是空)
基本输出函数 print
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) 将一系列的值以字符串形式输出到
标准输出设备上,默认为终端.
参数选项
选项的关键字参数为:
sep: 两个值之间的分隔符,默认为一个空格' '
end: 输出完毕后在流末尾自动追加一个字符串,默认为换行符'\n'
file: 流对象,默认为sys.stdout.
flush: 是否立即将流进行输出
字符串编码转换函数
函数 | 说明 |
ord(c) | 返回一个字符的Unicode值 |
chr(i) | 返回i这个值所对应的 字符 |
整数转换为字符串函数
函数 | 说明 |
hex(i) | 将整数转换为十六进制字符串 |
oct(i) | 将整数转换为八进制字符串 |
bin(i) | 将整数转换为二进制字符串 |
字符串构造函数
"123" + 1 # 不合法
函数 | 说明 |
str(obj='') | 将对象转换为字符串 |
range()函数
格式:
(见:help(range))
函数 | 意义 |
range(stop) | 从零开始,每次生成一个整数后加1操作,直到stop为止(不包含stop) |
range(start,stop[,step]) | 从start开始,每次生成一个整数后移动step,直到stop为止(不包含stop,且step可以是负整数) |
列表的构造(创建)函数list
函数 | 说明 |
list() | # 生成一个空的列表 等同于 [] |
list(iterable) | # 用可迭代对象创建一个列表 |
Python3中常用的序列函数
函数 | 说明 |
len(seq) | 返回序列的长度 |
max(x) | 返回序列的最大值的元素 |
min(x) | 返回序列的最小值的元素 |
------以上是以前学的--------- |
|
sum(x) | 返回序列中所有元素的和(元素必须是数值类型) |
any(x) | 真值测试,如果列表中其中一个值为真值则返回True |
all(x) | 真值测试,如果列表中所有值为真值则返回True |
reversed(seq) | 返回原序列反向顺序的可迭代对象 |
sorted(iterable, reverse=False) | 返回已排序对象的 |
str(obj) | 将对象obj序列化为一个字符串 |
list(iterable) | 用可迭代对象生成一个列表 |
tuple(iterable) | 用可迭代对象生成一个元组 |
元组的构造(创建)函数tuple
函数 | 说明 |
tuple() | 生成一个空的元组,等同于 () |
tuple(iterable) | 用可迭代对象生成一个元组 |
序列相关函数总结
函数 | 说明 |
len(seq) | 返回序列的长度 |
max(x) | 返回序列的最大值的元素 |
min(x) | 返回序列的最小值的元素 |
sum(x) | 返回序列中所有元素的和 |
any(x) | 真值测试,如果列表中其中一个值为真值则返回True |
all(x) | 真值测试,如果列表中所有值为真值则返回True |
str(obj) | 将对象obj序列化为一个字符串 |
list(iterable) | 用可迭代对象生成一个列表 |
tuple(iterable) | 用可迭代对象生成一个元组 |
reversed(seq) | 返回反向顺序的可迭代对象 |
sorted(iterable, key=None, reverse=False) | 返回已排序的列表 |
dict的构造(创建)函数dict
函数 | 说明 |
dict() | # 生成一个空的字典 等同于 {} |
dict(iterable) | 用可迭代对象初始化一个字典 |
dict(**kwargs) | 关键字传参形式生成一个字典 |
集合构造(创建)函数 set
函数 | 说明 |
set() | 创建一个空的集合对象(不能用{}来创建空集合) |
set(iterable) | 用可迭代对象创建一个新的集合对象 |
固定集合构造(创建)函数 frozenset
函数 | 说明 |
frozenset() | 创建一个空的固定集合对象 |
frozenset(iterable) | 用可迭代对象创建一个新的固定集合对象 |
globals() / locals() 函数
函数 | 说明 |
globals() | 返回当前全局作用域内变量的字典 |
locals() | 返回当前局部作用域内变量的字典 |
eval(), exec() 函数
函数 | 说明 |
eval(source, globals=None, locals=None) | 把一个字符串source当成一个表达式来执行,返回表达式执行后的结果 |
exec(source, globals=None, locals=None) | 把一个字符串source当成程序来执行. |
高阶函数 High Order Function
函数 | 说明 |
map(func, *iterables) | 用函数和对可迭代对象中的每一个元素作为参数计算出新的可迭代对象, 当最短的一个可迭代对象不再提供数据时此可迭代对象生成结束 |
filter(function, iterable) | 筛选可迭代对象iterable中的数据,返回一个可迭代器对象,此可迭代对象 将对iterable进行筛选.函数function 将对iterable中的每个元素进行求值,返回False则将此数据丢弃,返回True,则保留此数据 |
sorted(iterable, key=None, reverse=False) | 将原可迭代对象的数据进行排序,生成排序后的列表iterable 可迭代对象 key 函数是用来提供一个值,这个值将作为排序的依据reverse 标志用来设置是否降序排序 |
迭代器函数iter和next
函数 | 说明 |
iter(iterable) | 从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象 |
next(iterator) | 从迭代器iterator中获取一下个记录,如果无法获取一下条记录,则触发 StopIteration 异常 |
迭代工具函数
迭代工具函数的作用是生成一个个性化可迭代对象
函数 | 说明 |
zip(iter1 [,iter2 [...]]) | 返回一个zip对象, 此对象用于生成一个元组,此元组的个数由最小的可迭代对象决定 |
enumerate(iterable[, start]) | 生成带索引的枚举对象,返回的迭代类型为索引-值对(index-value)对,默认索引从零开始,也可以用start指定 |
字节串的构造函数bytes
函数 | 说明 |
bytes() | # 生成一个空的字节串 等同于 b'' |
bytes(整型可迭代对象) | # 用可迭代对象初始化一个字节串 |
bytes(整数n) | 生成n个值为0的字节串 |
bytes(字符串, encoding='utf-8') | 用字符串的转换编码生成一个字节串 |
字节数组的生成函数 bytearray
函数 | 说明 |
bytearray() | 创建空的字节数组 |
bytearray(整数) | 用可迭代对象初始化一个字节数组 |
bytearray(整型可迭代对象) | 生成n个值为0的字节数组 |
bytearray(字符串, encoding='utf-8') | 用字符串的转换编码生成一个字节数组 |
文件的打开函数
字符 | 含义 |
open(file, mode='rt') | 用于打开一个文件,返回此文件流对象. 如果打开文件失败,则会触发OSError 错误! 如果要打开的文件不存在,则会触发FileNotFoundError 错误! |
用于类的函数
函数 | 说明 |
isinstance(obj, class_or_tuple) | 返回这个对象obj 是否是 某个类的对象,或者某些类 中的一个类的对象,如果是返回True,否则返回False |
type(obj) | 返回对象的类型 |
|
|
super函数
函数 | 说明 |
super(cls, obj) | 返回绑定超类的实例(要求obj必须为cls类型的实例) |
super() | 返回绑定超类的实例,等同于:super(class, 实例方法的第一个参数),必须用在方法内调用 |
用于类的函数
函数 | 说明 |
issubclass(cls, class_or_tuple) | 判断一个类是否继承自其它的类,如果此类cls是class 或 tuple中的一个派生子类则返回True,否则返回False |
|
|
对象的属性管理函数
函数 | 说明 |
getattr(obj, name[, default]) | 从一个对象得到对象的属性;getattr(x, 'y') 等同于x.y; 当属性不存在时,如果给 出default参数,则返回default,如果没有给出default 则产生一个AttributeError错误 |
hasattr(obj, name) | 用给定的name返回对象obj是否有此属性,此种做法可以避免在getattr(obj, name)时引发错误 |
setattr(obj, name, value) | 给对象obj的名为name的属性设置相应的值value, set(x, 'y', v) 等同于 x.y = v |
delattr(obj, name) | 删除对象obj中的name属性, delattr(x, 'y') 等同于 del x.y |
1、new、init
__new__方法是真正的类构造方法,用于产生实例化对象(空属性)。重写__new__方法可以控制对象的产生过程。
__init__方法是初始化方法,负责对实例化对象进行属性值初始化,此方法必须返回None,__new__方法必须返回一个对象。重写__init__方法可以控制对象的初始化过程。# 使用new来处理单例模式
class Student:
__instance = None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
def sleep(self):
print('sleeping...')
stu1 = Student()
stu2 = Student()
print(id(stu1), id(stu2)) # 两者输出相同
print(stu1 is stu2) # True
个人感觉,__new__一般很少用于普通的业务场景,更多的用于元类之中,因为可以更底层的处理对象的产生过程。而__init__的使用场景更多。
2、str、repr
两者的目的都是为了显式的显示对象的一些必要信息,方便查看和调试。__str__被print默认调用,__repr__被控制台输出时默认调用。即,使用__str__控制用户展示,使用__repr__控制调试展示。
# 默认所有类继承object类,object类应该有一个默认的str和repr方法,打印的是对象的来源以及对应的内存地址
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu = Student('zlw', 26)
print(stu) # <__main__.Student object at 0x0000016ED4BABA90>
# 自定义str来控制print的显示内容,str函数必须return一个字符串对象# 使用repr = str来偷懒控制台和print的显示一致
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'{self.__class__}, {self.name}, {self.age}'
__repr__ = __str__
stu = Student('zlw', 26)
print(stu) # <class '__main__.Student'>, zlw, 26
3、call
__call__方法提供给对象可以被执行的能力,就像函数那样,而本质上,函数就是对象,函数就是一个拥有__call__方法的对象。拥有__call__方法的对象,使用callable可以得到True的结果,可以使用()执行,执行时,可以传入参数,也可以返回值。所以我们可以使用__call__方法来实现实例化对象作为装饰器:
# 检查一个函数的输入参数个数, 如果调用此函数时提供的参数个数不符合预定义,则无法调用。
# 单纯函数版本装饰器def args_num_require(require_num):
def outer(func):
def inner(*args, **kw):
if len(args) != require_num:
print('函数参数个数不符合预定义,无法执行函数')
return None
return func(*args, **kw)
return inner
return outer
@args_num_require(2)def show(*args):
print('show函数成功执行!')
show(1) # 函数参数个数不符合预定义,无法执行函数
show(1,2) # show函数成功执行!
show(1,2,3) # 函数参数个数不符合预定义,无法执行函数
# 检查一个函数的输入参数个数,# 如果调用此函数时提供的参数个数不符合预定义,则无法调用。
# 实例对象版本装饰器class Checker:
def __init__(self, require_num):
self.require_num = require_num
def __call__(self, func):
self.func = func
def inner(*args, **kw):
if len(args) != self.require_num:
print('函数参数个数不符合预定义,无法执行函数')
return None
return self.func(*args, **kw)
return inner
@Checker(2)def show(*args):
print('show函数成功执行!')
show(1) # 函数参数个数不符合预定义,无法执行函数
show(1,2) # show函数成功执行!
show(1,2,3) # 函数参数个数不符合预定义,无法执行函数
4、del
__del__用于当对象的引用计数为0时自动调用。
__del__一般出现在两个地方:1、手工使用del减少对象引用计数至0,被垃圾回收处理时调用。2、程序结束时调用。__del__一般用于需要声明在对象被删除前需要处理的资源回收操作# 手工调用del 可以将对象引用计数减一,如果减到0,将会触发垃圾回收
class Student:
def __del__(self):
print('调用对象的del方法,此方法将会回收此对象内存地址')
stu = Student() # 调用对象的__del__方法回收此对象内存地址
del stu
print('下面还有程序其他代码')
class Student:
def __del__(self):
print('调用对象的del方法,此方法将会回收此对象内存地址')
stu = Student() # 程序直接结束,也会调用对象的__del__方法回收地址
5、iter、next
这2个方法用于将一个对象模拟成序列。内置类型如列表、元组都可以被迭代,文件对象也可以被迭代获取每一行内容。重写这两个方法就可以实现自定义的迭代对象。
# 定义一个指定范围的自然数类,并可以提供迭代
class Num:
def __init__(self, max_num):
self.max_num = max_num
self.count = 0
def __iter__(self):
return self
def __next__(self):
if self.count < self.max_num:
self.count += 1
return self.count
else:
raise StopIteration('已经到达临界')
num = Num(10)for i in num:
print(i) # 循环打印1---10
6、getitem、setitem、delitem
重写此系列方法可以模拟对象成列表或者是字典,即可以使用key-value的类型。
class StudentManager:
li = []
dic = {}
def add(self, obj):
self.li.append(obj)
self.dic[obj.name] = obj
def __getitem__(self, item):
if isinstance(item, int):
# 通过下标得到对象
return self.li[item]
elif isinstance(item, slice):
# 通过切片得到一串对象
start = item.start
stop = item.stop
return [student for student in self.li[start:stop]]
elif isinstance(item, str):
# 通过名字得到对象
return self.dic.get(item, None)
else:
# 给定的key类型错误
raise TypeError('你输入的key类型错误!')
class Student:
manager = StudentManager()
def __init__(self, name):
self.name = name
self.manager.add(self)
def __str__(self):
return f'学生: {self.name}'
__repr__ = __str__
stu1 = Student('小明')
stu2 = Student('大白')
stu3 = Student('小红')
stu4 = Student('胖虎')
# 当做列表使用
print(Student.manager[0]) # 学生: 小明
print(Student.manager[-1]) # 学生: 胖虎
print(Student.manager[1:3]) # [学生: 大白, 学生: 小红]
# 当做字典使用
print(Student.manager['胖虎']) # 学生: 胖虎
7、getattr、setattr、delattr
当使用obj.x = y的时候触发对象的setattr方法,当del obj.x的时候触发对象的delattr方法。
当尝试访问对象的一个不存在的属性时 obj.noexist 会触发getattr方法,getattr方法是属性查找中优先级最低的。可以重写这3个方法来控制对象属性的访问、设置和删除。**特别注意:如果定义了getattr,而没有任何代码(即只有pass),则所有不存在的属性值都是None而不会报错,可以使用super().__getattr__()方法来处理**class Student:
def __getattr__(self, item):
print('访问一个不存在的属性时候触发')
return '不存在'
def __setattr__(self, key, value):
print('设置一个属性值的时候触发')
# self.key = value # 这样会无限循环
self.__dict__[key] = value
def __delattr__(self, item):
print('删除一个属性的时候触发')
if self.__dict__.get(item, None):
del self.__dict__[item]
stu = Student()
stu.name = 'zlw' # 设置一个属性值的时候触发
print(stu.noexit) # 访问一个不存在的属性时候触发 , 返回'不存在'del stu.name # 删除一个属性的时候触发
8、getatrribute
这是一个属性访问截断器,即,在你访问属性时,这个方法会把你的访问行为截断,并优先执行此方法中的代码,此方法应该是属性查找顺序中优先级最高的。
属性查找顺序:实例的getattribute-->实例对象字典-->实例所在类字典-->实例所在类的父类(MRO顺序)字典-->实例所在类的getattr-->报错class People:
a = 200
class Student(People):
a = 100
def __init__(self, a):
self.a = a
def __getattr__(self, item):
print('没有找到:', item)
def __getattribute__(self, item):
print('属性访问截断器')
if item == 'a':
return 1
return super().__getattribute__(item)
stu = Student(1)
print(stu.a) # 1
9、enter、exit
这两个方法的重写可以让我们对一个对象使用with方法来处理工作前的准备,以及工作之后的清扫行为。
class MySQL:
def connect(self):
print('启动数据库连接,申请系统资源')
def execute(self):
print('执行sql命令,操作数据')
def finish(self):
print('数据库连接关闭,清理系统资源')
def __enter__(self): # with的时候触发,并赋给as变量
self.connect()
return self
def __exit__(self, exc_type, exc_val, exc_tb): # 离开with语句块时触发
self.finish()
with MySQL() as mysql:
mysql.execute()
# 结果:# 启动数据库连接,申请系统资源# 执行sql命令,操作数据# 数据库连接关闭,清理系统资源