将其他语言翻译为机器语言的工具被称为编译器
编译器翻译的方式有两种,一个是编译、另一个是解释。两中方式的区别在于翻译时间的不同,当编译器以解释方式运行的时候,也称之为解释器
跨平台:每个操作系统都有对应的解释器,解释型跨平台性很好 速度:解释型速度相对来说较慢
python的设计哲学:最好只有一个方法来做一件事请,越简单越明确越好
Python2.X默认不支持中文,主要原因是编码不支持 Python2.X的解释器名称是Python Python3.X的解释器名称是Python3
Python3是主流版本,Python3.0并没有向下兼容,但是语法层面相差并不是很大
python# 单行注释
"""
这个是多行注释、也叫做块注释
"""
运算符 | 作用 |
---|---|
/ | 获得高精度结果 |
// | 或者整数除数 |
% | 获取余数 |
** | 幂,二次方 |
* | 此运算符还可以得到指定个数的字符串 |
(1)CPU会先把Python解释器程序复制到内存中
(2)Python解释器会根据语法规则,从上到下让CPU翻译Python代码
(3)负责执行翻译完成的代码
Python解释器到底有多大? Linux的python2.7版本的解释器只有3.4M
注意:Python变量的定义不需要定义类型,解释器会自动推导数据类型 type函数:查看变量的数据类型 在Python2.x中: type (2 ** 32) int类型 type ( 2 ** 64) long类型 在Python3.x中 type (2 ** 32) int类型 type ( 2 ** 64) int类型 Python3已经将原来的long也认为是int
Python非常适合做数学计算,并且自动处理大数字,例如计算2的10000次方都可以轻松计算出来!
(1)数字之间可以直接计算,包括double与int等不同类型的数据,只要是数字就可以运算 (2) 如果变量是bool类型,True对应的数字为1,False对应的数字为0 (3)+ 运算符可以拼接字符串 (4)字符串变量可以和数字用*连接 (5)数字型变量和字符型变量之间不能进行其他的计算
pwd = input("请输入密码\n") 注意:input函数只能得到字符串
int(x):将x转化为整数 float(x):将x转化为浮点数
%s
字符串
%d
有符号十进制整数,%06d
表示输出的整数显示位数,不足的地方用0补全
%f
浮点数,%0.2f
表示小数点后只显示两位
%%
输出%
注意这与C的printf函数的符号使用区别,这个是直接使用
%
链接的
import keyword print(keyword.kwlist)
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
import 关键字:导入工具包 python中变量名是区分大小写的
在开发python程序的时候Tab键和4个空格键不要混用,最好是直接用4个空格 if语句与下方的缩进是一个完整的代码块!
注意输入的只能是字符串,需要类型转换
age = int(input("请输入年龄:")) print("年龄:%d" % age)
Tab键可以统一向右缩进 Shift+Tab可以统一向左缩进
注意:if判断代码过长,可以加小括号换行,换行之后的条件必须加8个空格
##如何产生1-100的随机数? (第一个参数必须小于第二个参数)
import random print(random.randint(0, 100))
python中的+=
、-=
、/=
、*=
、%=
与C一样,//=
是取整除、**=
是幂赋值运算符
pythoni = 1
while i <= 9:
j = 1
while j <= i:
print("%d*%d=%d\t"% (i, j, i*j), end = "")
j += 1
i += 1
print()
符号 | 原意 |
---|---|
\\ | 反斜杠符号 |
\' | 单引号 |
\" | 双引号 |
\n | 换行 |
\t | 横向制表符 |
\r | 回车 |
封装函数的格式:注意函数命名应该符合命名规则
def 函数名(): 封装的代码
注意:不能在定义函数之前就使用函数,和C语言一致,或者先声明函数
F8 Step Over 可以单步执行代码,会把函数调用看作是一行代码直接执行 F7 Step Into 可以单步执行代码,如果是函数,会进入函数内部
pythondef my_fun():
"""
打印乘法表
:return:无返回值
"""
i = 1
while i <= 9:
j = 1
while j <= i:
print("%d*%d=%d\t"% (i, j, i*j), end = "")
j += 1
print()
i += 1
my_fun()
pythondef 函数名(参数1,参数2,参数3,...):
函数体
模块:以.py结尾的文件就是一个模块,本质就是工具包,里面有工具函数,要使用的时候用import导入即可 模块名也是标识符,必须符合命名规则,比如以数字开头的文件是无法导入的
Pyc文件,c是compiled,即是编译过的意思
非数字型都有的特点: 1、都是一个序列(sequence),也可以理解为容器 2、取值[] 3、遍历for in 4、计算长度、最大值、最小值、比较、删除 5、连接 + 和重复 * 6、支持切片
在其他的编程语言叫做数组
del关键字:使用delete关键字,简写为del del关键字本质上是用来将一个变量从内存中删除的 注意:如果使用del关键字讲一个变量从内存中删除,后续的代码就不能使用该变量了,在开发中最常用的是使用列表提供的方法去删除元素
元组与列表类似,不同之处在于元组的元素不能修改,列表使用 [ ] 定义,二元组使用 ( ) 定义
如果只想定义只有一个元素的元组: single_tuple = (4) # 这种做法是错误的,解释器会误以为是加了括号的int类型 single_tuple = (4,) # 这才是正确的另一方式,需要在后面加逗号
元组只有两个方法:
方法 | 作用 |
---|---|
元组.count(数据) | 求该数据在元组中的个数 |
元组.index(索引) | 取出元组中的数据 |
元组中通常保存的数据是不同的,实际开发中,除非能确认元组中的数据类型,否则针对元组的循环遍历需求并不是很多,元组的应用场景:
list(元组)、tuple(列表)
字典的循环遍历:
pythonstudent = {"name": "Tim",
"age": 20,
"scort": 66.6}
for k in student:
print("%s:%s"% (k, student[k]))
字典和列表的混合使用
pythonstudents = [{"name": "Tim","age": 40,"scort": 66.6},
{"name": "LiLiLaLaLa","age": 30,"scort": 66},
{"name": "Android","age": 20,"scort": 59.9},
]
for student in students:
for k in student:
print("%s:%s"% (k, student[k]))
print()
定义字符串使用" "
和 ''
都是可以的,一般使用" "
定义,和其他编程语言一致
注意:
1、虽然可以使用 \”
或者 \'
做字符串的转移,但是在实际开发中:
"
,可以使用 '
定义字符串'
,可以使用 "
定义字符串2、可以使用索引获取一个字符串中指定位置字符,索引计数从0开始 3、也可以使用for循环遍历字符
方法 | 功能 |
---|---|
len(字符串) | 获取字符串的长度 |
字符串.count(字符串) | 小字符串在大字符串中出现的次数 |
字符串.index(字符串) | 获得小字符串第一次出现的索引 |
pythonstr3 = "hello hello"
print(len(str3)) # 10
print(str3.count("hello")) # 2
print(str3.count("abc")) # 0 查找子串出现次数,传入不存在的子串得到结果为0
print(str3.index("lo")) # 3
print(str3.index("abc")) # 出错,查找子串位置是若传入不存在的子串就会出错
判断类型
方法 | 功能 |
---|---|
string.isspace() | 如果string中只包含空格则返回True |
string.isalnum() | 如果string中至少有一个字符并且所有字符都是字母或数字则返回true |
string.isalpha() | 如果string中至少有一个字符并且所有字符都是字母则返回true |
string.isdecimal() | 如果string中只包含数字,则返回True,全角数字 |
string.isdigit() | 如果string中只包含数字,则返回True,全角数字、(1)、\uoob2 |
string.isnumeric() | 如果string中只包含数字,则返回True,全角数字、汉字数字 |
string.istitle() | 如果string是标题化的(每个单词首字母大写)则返回True |
string.islower() | 如果string包含一个区分大小写的字符,并且这些(区分大小写的)字符都是小写,则返回True |
string.isupper() | 如果string包含一个区分大小写的字符,并且这些(区分大小写的)字符都是大写,则返回True |
查找和替换
方法 | 功能 |
---|---|
string.startwith(str) | 如果string以str开头则返回True |
string.endwith() | 如果string以str结尾则返回true |
string.find(str,start = 0,end = len(string)) | 检测str是否包含在string中,如果start和end指定范围,则只是检查是否在范围内部,若是则返回索引值,不是返回-1 |
string.rfind(str,start = 0,end = len(string)) | 与find函数类似,只不过是从右边开始查找 |
string.index(str,start = 0,end = len(string)) | 与find函数类似,只不过str不在string中会报错 |
string.rindex(str,start = 0,end = len(string)) | 与find函数类似,只不过是从右边开始 |
string.replace(old_str,new_str,num = string.count(old_str)) | 将string中的old_str替换成new_str,如果num指定,则替换不能超过num次 |
大小写转换
方法 | 功能 |
---|---|
string.capitalize(str) | 把字符串的第一个字母大写 |
string.title() | 把字符串的每个单词首字母大写 |
string.lower() | 转换string中的所有大写字母为小写 |
string.upper() | 转换string中的所有小写字母为大写 |
string.swapcase() | 反转string中的大小写 |
文本对齐
方法 | 功能 |
---|---|
string.ljust(width) | 返回原字符串右对齐,并使用空格填充至长度width的新字符串 |
string.ritle() | 返回原字符串左对齐,并使用空格填充至长度width的新字符串 |
string.center() | 返回原字符串居中对齐,并使用空格填充至长度width的新字符串 |
去除空白字符
方法 | 功能 |
---|---|
string.lstrip() | 截掉string左边的空白字符 |
string.rstrip() | 截掉string右边的空白字符 |
string.center() | 截掉string左右两边的空白字符 |
拆分和链接
方法 | 功能 |
---|---|
string.partition(str) | 把string分成一个3元素的元组(str前面,str, str后面) |
string.rpartition(str) | 类似于partition函数,只不过是从右边查找 |
string.split(str="",num) | 以str为分隔符切片string,如果num有指定值,则仅分割num+1个字符串,str默认包含'\r','\t','\n'和空格 |
string.splitlines() | 按照行('\r','\n','\r\n')分隔,返回一个包含各行作为元素的列表 |
string.join(seq) | 以string作为分隔符,将seq中所有的元素(的字符串表示)合并为一个新的字符串 |
字符串中的转义字符
'\t'
在控制台中输出一个制表符,协助在输出文本时垂直方向
保持对其
'\n'
在控制台输出一个换行符
**制表符的功能是在不使用表格的情况下在垂直方向按列对齐文本
转义字符 | 描述 |
---|---|
\ \ | 反斜杠符号 |
\' | 单引号 |
\" | 双引号 |
\n | 换行 |
\ t | 横向制表符 |
\r | 回车 |
判断是否是数字的三种方法:(开发中常用的还是isdecimal方法)
python# 都不能判断小数
num_str = "123"
print(num_str.isdecimal())
print(num_str.isdigit())
print(num_str.isnumeric())
# isdigit与isnumeric的强大之处
num_str2 = "⑴"
print(num_str2.isdecimal())
print(num_str2.isdigit())
print(num_str2.isnumeric())
# isnumeric的强大之处
num_str3 = "一千零一"
print(num_str3.isdecimal())
print(num_str3.isdigit())
print(num_str3.isnumeric())
pythonprint(str.find("abc")) # 查找不存在的字符串返回-1,index方法则会报错
print(str.replace("world", "python")) # replace方法执行完毕会返回一个字符串,而不会改变源字符串
字符串去除空格、切割字符串、拼接字符串
pythonprint(str.strip()) # 去除所有的空格
print(str.lstrip()) # 去除左边的空格
print(str.rstrip()) # 去除右边的空格
str = "hello#world#java#python"
split = str.split("#") # 按照#切割字符串,默认按照不可见字符进行切割
print(split)
join = "#".join(split) # 按照#合并字符串
print(join)
下标和切片 注意可以使用倒序的方式来使用下标
python# 将字符串转为列表,再得到逆序的字符串
str = "abcdefg"
str_list = list(str)
str_list.reverse()
print(''.join(str_list))
# 直接使用字符串切片功能逆转字符串
str = "abcdefgh"
print(str[::-1])
print(str[-1::-1])
Python的内置函数
函数 | 描述 | 备注 |
---|---|---|
len(item) | 计算容器中元素个数 | |
del(item) | 删除变量 | del有两种方式 |
max(item) | 返回容器中元素最大值 | 如果是字典、只是针对key比较 |
min(item) | 返回容器中元素最小值 | 如果是字典、只是针对key比较 |
cmp(item1,item2) | 比较两个值,-1 小于/ 0相等/ 1大于 | Python3.x取消了cmp函数 |
注意:字符串比较符合以下规则:"0"<"A"<"a"
python# 针对列表和元组进行切片
print([1, 2, 3, 4, 5][1:3])
print((1, 2, 3, 4, 5)[1:3])
# 由于字典是一个无序集合,使用键值对的方式保存数据,所以字典是无法切片的
python# 列表和元组乘法运算
print([1, 2]*5)
print((1, 2)*5)
# print({"a": "z"}) error,因为key是唯一的
# 列表
l_list = [1, 2]
l_list2 = [3, 4]
print(l_list+l_list2) # 使用加号不会改变原有的列表,而是产生新的列表
l_list.extend(l_list2) # 此方法无返回值,直接改变l_list
l_list.append(5)
l_list.append([6, 7, 8]) # append方法会把列表当成一个元素插入到列表中
print(l_list)
l_list3 = (1, 2)
l_list4 = (3, 4)
print(l_list3+l_list4)
int 与 not in运算符
pythonprint("a" in "abcde")
print("a" not in "abcde")
完整的for循环
pythonfor 变量 in 集合:
循环体代码
else:
没有通过break退出循环,只有当循环结束后才会执行的代码
pythonnum = [1, 2, 3, 4, 5]
for n in num:
if n == 3:
break
print(n)
else:
print("完毕")
pythonnum = [1, 2, 3, 4, 5]
for n in num:
print(n)
else:
print("完毕")
pass 关键字:pass代表空语句,就和java中的;是一样的 TODO(开发者姓名/开发者邮件) 功能描述 Linux上的Shebang符号(#!) 在要运行的python主文件在第一行加入 #! /usr/bin/python3即可,然后修改python文件权限为可执行!
注意:定义全局变量的时候应该在变量名前面加
g_
或者gl_
的前缀
变量一,变量二... = 函数
pythona = 10
b = 20
# 方式一
a = a+b
b = a-b
a = a-b
print("a = %d,b = %d" % (a, b))
# 方式二
a, b = (b, a)
print("a = %d,b = %d" % (a, b))
赋值语句
,都不会影响到调用函数时传递的实参变量,影响范围只在函数内部可变类型
,在函数内部,使用方法
修改了数据的内容,这样才会影响到外部数据+=
符号本质是在调用列表的extend
方法,所以仍然会修改函数外部的实参定义支持多值参数的函数
python
中有两种多值参数:
*
可以接受元组*
可以接受字典*args
-- 存放元组参数,前面有一个*
**kwargs
-- 存放 字典参数,前面有两个*
args
是arguments
的缩写,有变量的含义kw
是keyword
的缩写,kwargs
可以记忆为键值对参数多值参数常用于框架当中!
再调用带有多值参数的函数时,如果希望:
args
kwargs
就可以使用拆包,简化参数的传递,拆包的方式是:
*
*
使用示例:
pythondef demo(*args, **kwargs):
print(args)
print(kwargs)
gl_nums = (1, 2, 3)
gl_dict = {"name": "Tim", "age": 18}
demo(gl_nums, gl_dict)
很显然这不是我们所期望看到的结果,因为解释器把字典当做元组的一个元素了,此时便需要拆包
pythondef demo(*args, **kwargs):
print(args)
print(kwargs)
gl_nums = (1, 2, 3)
gl_dict = {"name": "Tim", "age": 18}
# demo(gl_nums, gl_dict)
# 拆包的做法
demo(*gl_nums,**gl_dict)
# 不拆包的做法
demo(1, 2, 3, name="Tim", age=18)
使用内置函数dir
传入标识符/数据,可以查看对象内部的所有属性和方法
提示__方法名__
格式的方法是python提供的内置方法/属性
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
01 | __new__ | 方法 | 创建对象时,会被自动调用 |
02 | __init__ | 方法 | 对象被初始化时,会被自动调用 |
03 | __del__ | 方法 | 对象被从内存中销毁前,会被自动调用 |
04 | __str__ | 方法 | 返回对象的描述信息,print函数输出使用 |
所以在Python中方法也是对象!!
pythonclass MyClass:
def fun(self):
pass
# 创建对象
obj = MyClass()
# print函数会直接打印出对象所属类以及地址
print(obj)
# 使用id函数获取 对象的内存地址
address = id(obj)
print(address)
# 以16进制打印地址
print("%x" % address)
在python中要给对象设置属性,非常容易,但是不推荐使用,因为对象的属性应该封装在类的内部,设置方法是对象.属性 = 值
,这种方式虽然简单但是不推荐使用!
哪一个对象调用的方法,self就是哪一个对象的引用
pythonclass Student:
def study(self):
print("%s开始学习" % self.name)
self.eat()
def eat(self):
pass
s1 = Student()
s1.name = "Tim"
s1.study()
self参数也可以访问到类中属性和方法,在开发中不推荐在类的外部给类增加属性,如果在运行时没找到属性,程序就会报错。所有属性都应该封装在类的内部
__init__
方法相当于Java中的构造方法!
当使用类名()
创建对象是,会自动分配空间并执行__init__
方法,__init__
是对象的内置方法,专门用来定义一个类具有哪些属性的方法,在__init__
方法内部使用self.属性名= 初始值
就可以定义属性!
对__init__
方法加上参数,就可以在__init__
内部使用self.属性 = 形参
接收外部传递的参数
在创建对象时,使用类名(属性1, 属性2...)
的形式即可完成对象的构造
__del__
方法就相当于C++中的析构函数!
当使用类名()
创建对象时,自动调用__init__
方法,当对象从内存中销毁之前,会自动调用__del__
方法
__init__
改造初始化方法,可以让创建对象更加灵活
__del__
如果希望在对象被销毁前做些事情,考虑使用__del__
方法
__init__
-------------->__del__
相当于Java的toString方法
直接使用print打印对象获得的结果是该对象的所属类和在内存中的地址,如果希望自定义内容,__str__
方法是不二之选!
is
或is not
,注意is
与==
的区别:
is
用来判断两个不舒服引用的对象是否是同一个,相当于Java的==
==
用来判断引用变量的值是否相等,相当于Java的equest
方法
在定义属性或者方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法
Python并没有真正意义上的私有
在给属性和方法命名时,实际是对名称做了一些特殊的处理,使的外界无法访问
处理方式:在名称前面加上_类名
=>_类名__名称
格式:class 类名(父类名)
子类继承父类的所有属性和方法
重写父类方法有两种情况
super()
就是使用spuer
类创建出来的对象调用父类方法的另一种方式,在Python2.x时,如果需要调用父类的方法,还可以使用
父类名.方法(self)
,这种方式目前在Python3.x还支持,但是不推荐使用
在开发中父类名
和super()
两种方式不要混用,如果使用当前子类名调用方法会形成递归调用,出现死循环
Java的get和set
子类可以有多个父类,并且具有所有父类的属性和方法
格式class 子类名(父类名1,父类名2... )
如果不同的父类中存在同名的方法,子类在调用父类中的方法时会不明确调用哪一个方法,所以开发时应该尽且避免这种容易产生混淆的情况!如果父类之间存在同名的属性或方法.应该尽量避免使用多继承!
__mor__
可以查看方法搜索顺序method reslution order
,主要是用于在多继承的时候判断方法、属性的调用路径pythonclass A:
pass
class B:
pass
class C(A, B):
pass
print(C.mro())
输出:[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
__mro__
的输出结果从左至右的顺序查找的object
是python为所有对象提供的基类,提供有一些内置的属性和方法,使用dir
函数查看
新式类:以object作为基类的类,推荐使用
经典类:不以object作为基类的类,不推荐使用
Python3.x中所有的类都是新式类
Python2.x中如果没有指定父类,则不会以object作为父类
新式类和旧式类在多继承时会影响到方法的搜索顺序,建议统一使用新式类
不同的子类对象,调用的相同的父类方法,产生不同的执行结果
增加代码的灵活度
以继承和重写父类方法为前提
是调用方法的技巧,不会影响到类的内部设计
每一个对象都有自己的独立的内存空间,保存各自不同的属性
每个对象的方法在内存中只有一份,在调用方法时,需要把对象的引用传递到方法内部
class AAA:
定义的类属于类对象
obj = AAA()
属于实例对象
在程序运行时,类同样会被加载到内存,在Python中类是一个特殊的对象
在程序运行时,类对象在内存中只有一份
除了封装实例的属性和方法外,类对象还可以拥有自己的属性和方法
通过类名.
的方式可以访问类的属性或者调用类的方法
示例需求
pythonclass Tool:
# 定义类属性
count = 0
def __init__(self, name):
self.name = name
# 让类属性的值加一
Tool.count += 1
t1 = Tool("AAA")
t2 = Tool("BBB")
t3 = Tool("CCC")
t4 = Tool("DDD")
print(t1.count) # 总创建了4个对象
在Python中属性的获取存在一个向上查找机制,首先在对象内部查找对象属性,没有的话就会向上查找类属性
所以访问类属性有两种方式:
类名.类属性
对象.类属性
(不推荐使用)
注意如果使用对象.类属性 = 值
赋值语句,只会对给对象添加一个属性,而不会影响到类属性的值
类方法与类属性一致,类方法是针对这个类而定义的方法,而不是针对对象定义的方法
语法如下:
pythonclass 类名:
@classmethod
def 类方法名(cls):
pass
类方法需要使用@classmethod
来标识,告诉解释器这是一个类方法
类方法的第一个参数应该是cls
cls
就是那一个类引用self
比较相似cls
通过类名.
的方式调用类方法时不需要传递cls
参数
在方法内部
可以通过cls.
访问类属性
可以通过cls.
调用类方法
如果一个方法需要访问实例属性,那么封装为实例方法,如果需要访问类属性,使用类名.
访问类属性
如果一个方法需要访问类属性,那么封装为类方法
如果一个方法既不需要访问实例属性,也不需要访问类属性,那么封装为静态方法
语法如下:
python@staticmethod
def 静态方法名称():
pass
@staticmethod
来标识,告诉解释器这是静态方法类名.
调用静态方法内存中只有一个该类的实例
None
,用来记录单例对象的引用__new__
方法is None
,调用父类方法并分配空间,并在类属性中记录结果使用**类名()**创建对象时,python的解释器会自动调用__new__
方法为对象分配空间
__new__
是一个由object
基类提供的内置静态方法,作用
python的解释器获取引用后,将引用作为第一个参数,传递给__init__
方法
重写
__new__
方法的代码非常固定!
重写__new__
方法一定要return super().__new__(cls)
否则Python的解释器得不到分配空间的对象引用,就不会调用对象的初始化方法
注意:__new__
是一个静态方法,在调用时需要主动传递cls
参数
pythonclass MusicPlayer(object):
# 记录第一个被创建对象的引用
instance = None
def __new__(cls, *args, **kwargs):
# 判断类属性是否为空对象
if cls.instance is None:
# 调用父类方法,为第一个对象分配空间
cls.instance = super().__new__(cls)
# 返回类属性保存的对象引用
return cls.instance
m1 = MusicPlayer()
m2 = MusicPlayer()
print(m1)
print(m2)
< __main__.MusicPlayer object at 0x000001F9A381F8D0> <__main__.MusicPlayer object at 0x000001F9A381F8D0>
上面的做法虽然可以完成单例,但是初始化方法还是执行了两次,稍加修改让init方法也执行一次
pythonclass MusicPlayer(object):
# 记录第一个被创建对象的引用
instance = None
# 初始化方法调用标记
init_flag = False
def __new__(cls, *args, **kwargs):
# 判断类属性是否为空对象
if cls.instance is None:
# 调用父类方法,为第一个对象分配空间
cls.instance = super().__new__(cls)
# 返回类属性保存的对象引用
return cls.instance
def __init__(self):
if MusicPlayer.init_flag is False:
super()
MusicPlayer.init_flag = True
print("init()...")
m1 = MusicPlayer()
m2 = MusicPlayer()
print(m1)
print(m2)
pythontry:
尝试执行的代码
except:
出现错误的处理
pythontry:
pass
expect 错误类型1:
# 针对错误类型1的处理
pass
expect 错误类型2:
# 针对错误类型2的处理
pass
expect Exception as result:
print("未知错误%s" % result)
pythontry:
# 尝试执行的代码
pass
expect 错误类型1:
# 针对错误类型1的处理
pass
expect 错误类型2:
# 针对错误类型2的处理
pass
except(错误类型3,错误类型4):
pass
except Exception as result:
# 打印错误信息
print(result)
else:
# 没有异常才会执行的代码
pass
finally:
# 必须要执行的代码
如果在某个函数中发生异常却未处理,异常会传递给调用方,会层层向上传递直到有遇到处理异常的代码为止,如果都没有处理此异常将会传递至主程序!
Python提供了一个Exception
异常类,如果希望抛出异常先创建一个Exception
的对象,然后使用raise
关键字抛出异常对象即可!
import 模块名1,模块名2
不推荐使用,每个导入应该独占一行import 模块名 as 名称简写
给模块起别名from 模块名 import 工具名
从某一个模块中导入部分工具,这种方式导入的话不需要通过模块名.
的方式来访问的,导入之后可以直接使用模块提供的工具-----全局变量、函数、类注意如果两个模块存在同名的函数,那么后导入的模块的函数会覆盖先导入的函数!
from 模块名 import *
这样可以一次性把模块中的所有工具全部导入,不推荐使用搜索当前目录指定模块名的文件,如果有就直接导入,没有的话再搜索系统目录
注意:在开发时给文件起名不要和系统模块文件重名!
Python中每一个模块都有一个内置属性__file__
可以查看模块的完整路径
在导入文件时,文件中所有没有任何缩进的代码都会被执行一遍
应用场景:模块的开发者通常会在模块下方增加一些测试代码,仅仅在模块内补使用,不会被到导入到其他文件中
__name__属性
__name__
属性可以做到,测试模块的代码只在测试情况下运行,而被导入时不会被执行
__name__
时python的一个内置属性,记录着一个字符串
如果是被其他文件导入的,__name__
就是模块名
如果是当前执行的程序,__name__
是__main__
pythonif __name__ == "__main__":
# 测试代码
pass
包下必须有一个特殊的文件__init__.py
,使用import 包名
可以导入包下所有的模块
__init__.py
中指定对外提供的模块列表python# 从当前目录导入模块列表
from . import 模块名
setup.py
文件,关于字典参数的详细信息,http://docs.python.org/2/distutils/apiref.htmlpython2 setup.py build
puthon3 setup.py sdist
tar -zxvf 文件名
sudo python3 setup.py install
cd /usr/local/lib/python3.5/dist-packages
再sudo rm -f XXX
即可卸载pip是一个通用的python包管理工具,提供了对Python包的查找、下载、安装、卸载等功能
例如安装pygame这个模块sudo pip install pygame
但是这样只能将模块安装到Python2.x环境,如果需要安装到Python3.x的环境,需要使用sudo pip3 install pygame
在Python中操作文件需要记住1个函数3个方法
函数/方法 | 说明 |
---|---|
open(函数) | 打开文件,并且返回文件操作对象 |
read | 将文件读取到内存 |
write | 将指定内容写入文件 |
close | 关闭文件 |
open函数默认以只读方式打开文件,并且返回文件对象
访问方式 | 说明 |
---|---|
r | 以只读方式打开,这是默认模式,如果文件不存在则抛出异常 |
w | 以只写方式打开文件,如果文件存在会被覆盖,如果文件不存在则创建新文件 |
a | r+以追加方式打开文件,如果文件存在,文件指针将会放到末尾,若不存在创建新文件 |
r+ | 以读写方式打开文件,文件的指针将会放在文件的开头,如果文件不存在,抛出异常 |
w+ | 以读写方式打开文件,如果文件存在,文件指针将会放在文件的开头,如果不存在创建新文件 |
a+ | 以读写方式打开文件,如果文件已经存在,文件指针将会放在文件的结尾,若不存在就创建新文件写入 |
pythonfile = open("a.txt", "r")
while True:
text = file.readline()
if not text:
break
print(text, end="")
创建、重命名、删除、更改路径、查看目录内容...
Python 中如果希望通过程序实现上述功能需要导入os
模块
方法名 | 说明 | 示例 |
---|---|---|
rename | 重命名文件 | os.rename(源文件名,目标文件名) |
remove | 删除文件 | os.remove(文件名) |
方法名 | 说明 | 示例 |
---|---|---|
listdir | 目录列表 | os.listdir(目录名) |
mkdir | 创建目录 | os.mkdir(目录名) |
rmdir | 删除目录 | os.rmdir(目录名) |
getcwd | 获取当前目录 | os.getcwd() |
chdir | 修改工作目录 | os.chdir(目标目录) |
path.isdir | 判断是否是文件 | os.psth.isdir(文件路径) |
注意:文件或者目录都支持相对路径和绝对路径
ASCII
编码,UNICODE
编码ASCII
编码UTF-8
编码在Python2.x文件的第一行增加以下注释,解释器会以UTF-8
编码来处理文件,这也是官方推荐的方式
python# *-* coding:utf8 *-*
Python2.x中使用中文字符串需要在字符串前面加小写u,例如str = u"中文"
即可!
基本的数学计算,与JavaScript中的eval函数一致
pythonIn [1]: eval("5-3")
Out[1]: 2
In [2]: eval("'*' * 10")
Out[2]: '**********'
In [3]: type(eval("[1, 2, 3, 4, 5]"))
Out[3]: list
In [4]: type(eval("{'name':'Tim', 'age':20}"))
Out[4]: dict
注意在开发时不要使用eval函数转换input的结果!
一旦用户输入__import__('os').system('终端命令')
这样的是非常可怕的!
is
是比较两个引用是否指向了同一个对象,即比较地址是否相同==
是比较两个对象的值是否相等pythonIn [1]: a = 10
In [2]: b = 10
In [3]: a == b
Out[3]: True
In [4]: a is b
Out[4]: True
In [5]: a = 257
In [6]: b = 257
In [7]: a == b
Out[7]: True
In [8]: a is b
Out[8]: False
pythonIn [1]: a = [1, 2, 3]
In [2]: b = a
In [3]: id(a)
Out[3]: 3143865105928
In [4]: id(b)
Out[4]: 3143865105928
In [5]: import copy as cp
In [6]: c = cp.deepcopy(a)
In [7]: id(a)
Out[7]: 3143865105928
In [8]: id(c)
Out[8]: 3143864558088
pythonIn [1]: a = [11, 22, 33]
In [2]: b = [44, 55, 66]
In [3]: c = [a, b]
In [4]: d = c
In [5]: id(c)
Out[5]: 2236861508936
In [6]: id(d)
Out[6]: 2236861508936
In [7]: import copy as cp
In [8]: e = cp.deepcopy(c)
In [9]: id(e)
Out[9]: 2236861766984
In [10]: a.append(44)
In [11]: e[0]
Out[11]: [11, 22, 33]
pythonIn [1]: a = [11, 22, 33]
In [2]: import copy as cp
In [3]: b = cp.copy(a)
In [4]: id(a)
Out[4]: 2909126778056
In [5]: id(b)
Out[5]: 2909126747464
In [6]: a.append(44)
In [7]: a
Out[7]: [11, 22, 33, 44]
In [8]: b
Out[8]: [11, 22, 33]
In [9]: a = (11, 22, 33)
In [10]: b = cp.copy(a)
In [11]: id(a)
Out[11]: 2909126674544
In [12]: id(b)
Out[12]: 2909126674544
pythona = "abc"
b = a[:]
pythonIn [13]: d = dict(name="Tim", age=10)
In [14]: co = d.copy()
In [15]: id(d)
Out[15]: 2909126284992
In [16]: id(co)
Out[16]: 2909126780176
pythonIn [17]: a = list(range(10))
In [18]: b = list(a)
In [19]: b
Out[19]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [20]: id(b)
Out[20]: 2909126777096
In [21]: id(a)
Out[21]: 2909126776456
在计算机科学领域已被广泛应用。它是一类在运行时可以改变其结构的语语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。动态语言非常具有活力。例如JavaScript便是动态语言,除此之外如PHP 、 Ruby 、 Python 等也都属于动态语言,C 、 C++ 则不属于动态语言!
这个比较简单,格式:对象.属性 = 值
即可
格式:类名.属性 = 值
即可
python#-*- coding:utf-8 -*-
import types
class Person(object):
def __init__(self, newName, newAge):
self.name = newName
self.age = newAge
def eat(self):
print("----%s正在吃----" % self.name)
p = Person("老王", 20)
p.eat()
# 给对象绑定方法
def run(self):
print("----%s正在跑----" % self.name)
p.run = types.MethodType(run, p)
p.run()
# 给Person类绑定类方法
@classmethod
def testClassMethod(cls):
print("class method")
Person.testclass = testClassMethod
Person.testclass()
# 给Person类绑定静态方法
@staticmethod
def testStaticMethod():
print("static method")
Person.teststatic = testStaticMethod
Person.teststatic()
动态语言:可以在运行的过程中,修改代码
静态语言:编译器时期就已经确定代码,运行过程中不能修改
如果我们想要限制实例的属性怎么办?⽐如,只允许对Person实例添加name和age属性。 为了达到限制的⽬的,Python允许在定义class的时候,定义⼀个特殊的__slots__变量,来限制该class实例能添加的属性:
pythonIn [1]: class Person(object):
...: __slots__ = ("name", "age")
...:
In [2]: p = Person()
In [3]: p.name = "XXX"
In [4]: p.age = 20
In [5]: p.other = "---"
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-dbbcced1d9ea> in <module>()
----> 1 p.other = "---"
AttributeError: 'Person' object has no attribute 'other'
注意
在⼤多数编程语⾔中,类就是⼀组⽤来描述如何⽣成⼀个对象的代码段。在Python中这⼀点仍然成⽴!
Python中的类还远不⽌如此。类同样也是⼀种对象。是的,没错,就是对象。只要你使⽤关键字class,Python解释器在执⾏的时候就会创建⼀个对象!
pythonIn [1]: class Person:
...: pass
...:
...:
In [2]: print(Person)
<class '__main__.Person'>
将在内存中创建⼀个对象,名字就是ObjectCreator。这个对象(类对象ObjectCreator)拥有创建对象(实例对象)的能⼒。但是,它的本质仍然是⼀个对象,于是乎你可以对它做如下的操作:
python>>> print ObjectCreator # 你可以打印⼀个类,因为它其实也是⼀个对象
<class '__main__.ObjectCreator'>
>>> def echo(o):
… print o
…
>>> echo(ObjectCreator) # 你可以将类做为参数传给函数
<class '__main__.ObjectCreator'>
>>> print hasattr(ObjectCreator, 'new_attribute')
Fasle
>>> ObjectCreator.new_attribute = 'foo' # 你可以为类增加属性
>>> print hasattr(ObjectCreator, 'new_attribute')
True
>>> print ObjectCreator.new_attribute
foo
>>> ObjectCreatorMirror = ObjectCreator # 你可以将类赋值给⼀个变量
>>> print ObjectCreatorMirror()
<__main__.ObjectCreator object at 0x8997b4c>
因为类也是对象,你可以在运⾏时动态的创建它们,就像其他任何对象⼀样。⾸先,你可以在函数中创建类,使⽤class关键字即可!
pythonIn [1]: def chose_class(name):
...: if name == "foo":
...: class Foo(object):
...: pass
...: return Foo # 返回的是类,而不是类的实例
...: else:
...: class Bar(object):
...: pass
...: return Bar
...:
In [2]: MyClass = chose_class("foo")
In [3]: print(MyClass)
<class '__main__.chose_class.<locals>.Foo'>
In [4]:
但这还不够动态,因为你仍然需要..编写整个类的代码。由于类也是对象,所以它们必须是通过什么东.来.成的才对。当你使.class关键字时,Python解释器自动创建这个对象。但就和Python中的大多数事情一样,Python仍然提供给你自动处理的方法。
pythonIn [4]: print(type(100))
<class 'int'>
In [5]: print(type("Hello XPU"))
<class 'str'>
In [6]: print(type(MyClass))
<class 'type'>
类对象的类型居然是type
!!!
type还有一种完全不同的功能,动态的创建类。 type可以接受一个类的描述作为参数,然后返回一个类(要知道,根据传入参数的不同,同一个函数拥有两种完全不同的用法是件很傻的事情,但这在Python中是为了保持向后兼容性)
type(类名,由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
pythonIn [7]: class Person:
...: nums = 0
...:
In [8]: MyPerson = type("MyPerson",(),{"num":0})
In [9]: p1 = Person()
In [11]: p1.nums
Out[11]: 0
In [12]: p2 = MyPerson()
In [13]: p2.num
Out[13]: 0
pythonIn [1]: Foo = type("Foo", (),{"bar":True})
In [2]: class Foo2(object):
...: bar = True
...:
注意
pythonIn [1]: Foo = type("Foo", (),{"bar":True})
In [2]: class Foo2(object):
...: bar = True
...:
In [3]: def my_fun(self):
...: print(self.bar)
...:
In [4]: FooChild = type('FoodChild',(Foo,), {'echo_bar':my_fun})
In [5]: my_foo = FooChild()
In [6]: my_foo.echo_bar()
True
同上,需要在方法上面加注@staticmethod
即可
同上,需要在方法上面加注@classmethod
即可
在Python中,类也是对象,你可以动态的创建类。这就是当你使⽤关键字class时Python在幕后做的事情,⽽这就是通过元类来实现的!
元类就是⽤来创建类的“东⻄”。你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。
函数type实际上是⼀个元类。type就是Python在背后⽤来创建所有类的元类。现在你想知道那为什么type会全部采⽤⼩写形式⽽不是Type呢? 好吧,我猜这是为了和str保持⼀致性,str是⽤来创建字符串对象的类,⽽int是⽤来创建整数对象的类。type就是创建类对象的类!可以通过检查__class__属性来看到这.点。Python中所有的东西都是对象。这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来,这个类就是type。
定义⼀个类的时候为其添加__metaclass__属性
pythonclass Foo(object):
__metaclass__ = something...
如果你这么做了,Python就会⽤元类来创建类Foo。⼩⼼点,这⾥⾯有些技巧。你⾸先写下class Foo(object),但是类Foo还没有在内存中创建。Python会在类的定义中寻找__metaclass__属性,如果找到了,Python就会⽤它来创建类Foo,如果没有找到,就会⽤内建的type来创建这个类。把下⾯这段话反复读⼏次。当你写如下代码时:
pythonclass Foo(Bar):
pass
Python做了如下的操作:
Foo中有__metaclass__
这个属性吗?如果是,Python会通过__metaclass__
创建⼀个名字为Foo的类(对象)
如果Python没有找到__metaclass__
,它会继续在Bar(⽗类)中寻找__metaclass__
属性,并尝试做和前⾯同样的操作
如果Python在任何⽗类中都找不到__metaclass__
,它就会在模块层次中去寻找__metaclass__
,并尝试做同样的操作
如果还是找不到__metaclass__
,Python就会⽤内置的type来创建这个类对象
你可以在__metaclass__
中放置些什么代码呢?答案就是:可以创建一个类的东西。那么什么可以用来创建一个类呢?type,或者任何使用到type或者子类化type的东西都可以!
你决定在你的模块⾥所有的类的属性都应该是⼤写形式。有好⼏种⽅法可以办到,但其中⼀种就是通过在模块级别设定__metaclass__
采⽤这种⽅法,这个模块中的所有类都会通过这个元类来创建,我们只需要告诉元类把所有的属性都改成⼤写形式就万事⼤吉了!
Python2.x中的写法:
python#-*- coding:utf-8 -*-
def upper_attr(future_class_name, future_class_parents, future_class_attr):
# 便利属性字典,将不是__开头的属性名字变为大写
newAttr = {}
for name,value in future_class_attr.items():
if not name.startswith("__"):
newAttr[name.upper()] = value
# 调用type来创建一个类
return type(future_class_name,future_class_parents, newAttr)
class Foo(object):
__metaclass__ = upper_attr # 设置Foo类的元类为upper_attr
bar = 'bip'
print(hasattr(Foo, 'bar'))
print(hasattr(Foo, 'BAR'))
f = Foo()
print(f.BAR)
Python3.x的写法
python#-*- coding:utf-8 -*-
def upper_attr(future_class_name, future_class_parents, future_class_attr):
# 便利属性字典,将不是__开头的属性名字变为大写
newAttr = {}
for name,value in future_class_attr.items():
if not name.startswith("__"):
newAttr[name.upper()] = value
# 调用type来创建一个类
return type(future_class_name,future_class_parents, newAttr)
class Foo(object, metaclass=upper_attr): # 设置Foo类的元类为upper_attr
bar = 'bip'
print(hasattr(Foo, 'bar'))
print(hasattr(Foo, 'BAR'))
f = Foo()
print(f.BAR)
两者的区别只是__metaclass
的位置不一样!
就是这样,除此之外,关于元类真的没有别的可说的了。但就元类本身⽽ ⾔,它们其实是很简单的:
"Yuan is the magic of depth, and 99% of households should not have to do so. If you want to find out if you need to go to a meta class, you don't need it. Those that are actually metaclasses often know exactly what they need to do, and there is no need to explain why they need metaclasses at all. " Tim Peters, the leader of the Python world!
import XXX
是在当前目录找模块,如果需要其他路径的模块:
pythonimport sys
sys.path.append("XXX路径")
如果在导入模块之后,模块又发生了修改,此时需要重新导入
reload(模块名)
这样便可以重新加载模块,使用此函数的前提是form imp import *
a.py
pythonfrom b import b
print '---------this is module a.py----------'
def a():
print("hello, a")
b()
a()
b.py
pythonfrom a import a
print '----------this is module b.py----------'
def b():
print("hello, b")
def c():
a()
c()
运行a.py发现a和b这两个模块是相互导入的,这样就会出现循环导入的问题!
在计算机用一个数的最高位存放符号, 正数为0, 负数为1
正数的原反补码都一样
负数的反码是在原码的基础上,符号位不变其他位取反
负数的补码是在反码的基础上+1
负数从补码转换为原码的规则:补码的符号位不变——>数据位取反——>尾部+1
二进制是以0b
开头,十六进制以0x
开头
python# 十进制转二进制
In [1]: bin(10)
Out[1]: '0b1010'
# 二进制转十进制
In [2]: int("1001", 2)
Out[2]: 9
# 十进制转十六进制
In [3]: hex(10)
Out[3]: '0xa'
# 十六进制转十进制
In [4]: int("ff",16)
Out[4]: 255
# 十六进制转二进制
In [5]: bin(0xa)
Out[5]: '0b1010'
&
:全为1结果才是1|
:只要有一个为0结果就是1^
:只要不相同就是1~
:各个位于原来的相反<<
:各个二进制位全部左移n位,低位补0>>
:各个二进制位全部右移n位,保持符号位不变python#-*- coding:utf-8 -*-
a = 10
b = 20
a = a^b
b = a^b
a = a^b
print(a)
print(b)
__名字
的,子类不继承,子类不能访问_名字
的变量、函数、类在使用from xxx import *
时都不会被导入pythonclass Money(object):
def __init__(self):
self.__money = 0
def getMoney(self):
return self.__money
def setMoney(self, value):
if isinstance(value, int):
self.__money = value
else:
print("error:不是整型数字")
pythonclass Money(object):
def __init__(self):
self.__money = 0
def getMoney(self):
return self.__money
def setMoney(self, value):
if isinstance(value, int):
self.__money = value
else:
print("error:不是整型数字")
money = property(getMoney, setMoney)
@property
成为属性函数。可以对属性赋值时作必要的检查,并且保证代码的清晰短小
pythonclass Money(object):
def __init__(self):
self.__money = 0
@property
def money(self):
return self.__money
@money.setter
def money(self, value):
if isinstance(value, int):
self.__money = value
else:
print("error:不是整型数字")
这样访问是就可以直接使用对象.属性
的方式访问,但是本质还是去调用方法!
本文作者:Tim
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!