python基础02

模块

使用import可以直接导入模块,导入模块的同时会执行其中的代码,但是同一个模块的代码不论直接import多少次,都只执行一次

在python下py后缀名的文件就是模块

方法一:

1
2
import m
print(m.g_number1)

方法二:

1
2
from m import g_number1
print(g_number1)

方法三:

1
2
from m import *
print(g_number1)

模块的私有属性(不会被直接访问到的)以单下划线开头的全局变量不能被其他模块以import xxx from *的方式访问

1
_pnumber = 10

访问模块私有的属性

1
2
import m
print(m._pnumber)

python面向对象

python中的类,class类名(基类名称):

在python3中所有的类都默认继承自object

1
2
3
4
5
6
7
8
class Student:
#所有的构造函数都叫做__init__
def __init__(self):
pass
#所有的析构函数都叫做__del__
def __del__(self):
pass
#如果不编写这两个函数,会默认生成

类属性的添加和使用,可以使用类名在类内或者类外动态的添加新的类属性。虽然类名和实例都可以访问到类属性,但是更推荐使用类名。不能使用实例修改类属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Obj(object):
#在类的作用于中直接编写的属性就是类属性
#类属性类似与c++中的静态数据成员
class_number = 100
#调用这个方法就会生成一个新的类属性
def add_number(self):
Obj.class_number2 = 200

obj=Obj()
#可以使用类名和实例访问到类属性
print(obj.class_number, Obj.class_number)
# 使用类名可以直接修改类属性,如果尝试使用实例
# 修改属性,本质上是给实例添加了一个自己的属性
Obj.class_number = 200
print(obj.class_number, Obj.class_number)

image-20191203143546392

__dict__是一个字典,保存了当前的实例或者对象中的所有属性,包括内置属性和自定义属性

1
print(obj.__dict__, "\n", Obj.__dict__)

image-20191203143702572

可以在成员方法或类外使用类名动态的添加属性

1
2
3
4
5
6
7
8
9
class Obj(object):
def add_number(self):
Obj.class_number2 = 200

obj = Obj()
Obj.class_number1 = 100
print(Obj.class_number1, Obj.__dict__)
obj.add_number()
print(Obj.class_number2, Obj.__dict__)

image-20191203144003719

实例属性就是使用self或者实例名定义出来的属性,每一个实例都会拥有自己的实例属性,同样可以使用类名或者self动态添加属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Obj(object):
# 构造函数中添加的实例属性是每一个实例都有的
def __init__(self):
self.number1 = 10

# 调用这个函数会动态添加属性
def add_number2(self):
self.number2 = 20

# 创建两个实例分别测试
object1 = Obj()
object2 = Obj()
print(object1.__dict__, "\n", object2.__dict__)
# 动态的使用 self 添加属性
object1.add_number2()
print(object1.__dict__, "\n", object2.__dict__)
# 动态的使用 实例名称 添加属性
object2.number3 = 30
print(object1.__dict__, "\n", object2.__dict__)
# 删除一个属性
del object1.number2
print(object1.__dict__, "\n", object2.__dict__)

image-20191203144225361

1
2
3
4
5
6
class Obj(object):
def __init__(self):
# 所有的基类组成的一个元组
print(Obj.__bases__)
# 并不是所有的属性都能够被遍历到
obj = Obj()

image-20191203144500944

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Obj(object):
#一个类属性
class_number = 10

# 实例方法必须使用实例调用
# 第一个参数是一个指向当前对象的'指针',
# 名字通常是 self ,参数自行添加
def function1(self):
print("这是一个实例方法", Obj.class_number)

# 使用 @classmethod 修饰的方法就是类方法,
# 类方法的第一个参数就是类本身,通常叫做 cls
# 可以使用 cls 访问到当前类的类属性
@classmethod
def function2(cls):
print("这是一个类方法", cls.class_number)

# 在使用时和类方法没有太大区别,
# 对参数没有要求,如果想要访问类属性可以直接通过类名
@staticmethod
def function3():
print("这是一个静态方法", Obj.class_number)

obj = Obj()
obj.function1()
obj.function2()
obj.function3()

image-20191203145208302

类的”私有”属性,所有只以双下划线开头的属性会被认为是私有的,不能[直接]被外界访问到

1
2
class Obj(object):
__number = 100

实际上的私有知识解释器给属性进行了更名,_类名+属性名

但是可以使用这种方式进行访问Obj._Obj__number

所有以单下划线开头的命名,约定俗成都是不可访问的

继承

继承的形式,class 类名(父类名, … )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class CBase1(object):
def __init__(self):
print("CBase1")

class CBase2(object):
def __init__(self):
print("CBase2")

class CObj(CBase1, CBase2):
def __init__(self):
print("CObj")
# 可以使用父类的类名直接
# 访问父类的属性
CBase1.__init__(self)
# 默认调用的是原型链中
# 当前类的下一个
super().__init__()
# super实际找到的类就是第
# 一个参数在原型链中的下一个
super(CBase1, self).__init__()
obj = CObj()

image-20191203150040811

判断一个类是不是另一个类的子类

1
print(issubclass(CObj, CBase1))

输出当前所有父类组成的元祖

1
print(CObj.__bases__)

显示当前类的继承原型链

1
print(CObj.mro())

python存在继承关系时,不会出现二义性问题,当访问一个属性的时候,解释器会遍历原型链,首先找到谁就用谁

异常

如果一部分代码可能会触发异常,就应该使用try进行包含

1
2
3
4
5
6
7
try:
#aaa = 1
print(aaa)
except NameError:
print("产生了一个异常")
else:
print("程序正常运行没有产生异常")

NameError是一个异常对象的类名,这里表示会堆找不到名称这个异常捕获并处理

try finally 无论是否产生异常,都保证执行代码

1
2
3
4
try:
print("没有异常")
finally:
print("永远会执行")

通用的异常处理写法

1
2
3
4
5
6
try:
#aaa = 1
print(aaa)
# 接收任意一个异常对象并取名字
except Exception as e:
print(e)

抛出异常

1
2
3
name = input("请输入姓名:")
if name == "hello":
raise NameError("输入姓名异常")

image-20191203151224707

产生异常的时候,异常的类型可以在输出窗口看到

python特殊函数

特殊函数filter :接收一个序列,将序列中的每一个元素传入到提供的函数中进行判断,如果函数的返回值位True那么将这个元素添加到新的的序列中

1
2
3
4
5
6
7
8
9
# 筛选出所有字符
def filter_alpha(param):
# 传入所有的元素,但只留下返回值为True的
#print(param)
# isalpha 是 str 的方法,判断是否是字母
# islower 是 str 的方法,判断是否是小写
return param.isalpha() and param.islower()

print(list(filter(filter_alpha, "A1!b2#C3%d4^E5&f6")))

image-20191203151652289

特殊函数reduce:接收一个序列和函数,函数必须拥有两个参数。首先将序列的第一个元素和第二个元素作为参数传入到函数中,之后的每一次都将前一次的计算结果和下一个元素传入到函数中,最终返回计算结果

1
2
3
4
5
6
7
8
9
10
# 必须要有两个参数
def add(num1, num2):
return num1 + num2
def mul(num1, num2):
return num1 * num2
# 在python3中reduce不再是内置函数
# 需要使用functools模块
from functools import reduce
print(reduce(add,range(101)))
print(reduce(mul,range(1, 25)))

image-20191203152052423

特殊函数map:map要求传入一个函数以及一个或多个的可迭代序列,函数的参数个数必须和序列的数量相同,map会在内部分别将每一个序列的元素传入到提供的函数中,并且把函数的返回值组合成一个新的可迭代序列

1
2
3
def rep_string(s, time):
return s * time
print(list(map(rep_string, "abcd", [1, 2, 3, 4])))

image-20191203152353324

lambda表达式

lambda表达式的语法 lambda 参数名:实现

实现部分只能有一条语句,且不能有 return,整个实现部分的结果就是函数的返回值

1
2
3
print(list(map(lambda a, b:a * b, "abcd", [1, 2, 3, 4])))
print(reduce(lambda x, y:x + y, range(1, 101)))
print(list(filter(lambda n: True if n.isalpha() else False, "A1!b2#C3%d4^E5&f6")))

image-20191203153230826

闭包

闭包指内部函数使用外部函数作用域的变量

1
2
3
4
5
6
7
8
def outer(factor):
# 作用于:其中有 factor 和 inner
def inner(number):
return number * factor
return inner

fun = outer(10)
print(fun(20))

image-20191203153500061

1
2
3
4
5
6
fun = outer(10)
'''
在执行到本行代码的时候,会返回一个内部函数
def inner(number):
return number * 10
'''
1
2
3
4
5
6
print(fun(20))
'''
fun接收了上一个函数的返回值,已经是一个函数了
def inner(20):
return 20 * 10
'''

装饰器:在闭包的基础上,内部函数调用了外部作用于提供的函数

1
2
3
4
5
6
def outer(func):
def inner():
print("执行之前的时间")
func()
print("执行之后的时间")
return inner

有些时候,我们需要给一些特定的函数添加功能,但是不能修改函数的名称,函数的参数个数以及函数的调用形式,可以在装饰器中实现功能

1
2
3
4
5
6
7
8
9
10
def outer(func):
def inner():
print("执行之前的时间")
func()
print("执行之后的时间")
return inner
def fun():
print("fun函数原有功能")
fun=outer(fun)
fun()

image-20191203154153209

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 传入了一个函数,返回了一个新的函数
# 并且将新函数的地址赋值给fun
fun=outer(fun)
'''
def inner():
print("这里是在原有函数上新添加的功能")
return 以前的fun()
'''
fun()
'''这里是返回的新的函数
def fun():
print("这里是在原有函数上新添加的功能")
return 以前的fun()
'''

@outer 在python中@的是语法糖

语法糖是为了让代码可读性更高使用更简单

1
arr[10][10] -> *(*(arr+10)+10)

常用模块

时间模块time

1
2
3
4
5
6
7
8
import time
# 使用localtime可以获取元祖显示的当前时间
# 如果传入了一个时间戳,那么会将时间戳进行转换
print(time.localtime())
# 休眠指定秒数
time.sleep(1)
# 将时间元祖转化成字符串
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))

随机数模块random

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import random
for i in range(100):
# 可以接受一个参数,生成的是0~n(不包括n)
print(random.randrange(10))
# 要求两个参数,生成n~m(包含m)
print(random.randint(0,10))

tmp = ""
# 一共循环了 0 ~ 5 次
for i in range(6):
# 有一半的概率是数字或者字母
rad1 = random.randrange(4)
if rad1 == 1 or rad1 == 3:
# 生成 0 ~ 9 数字
rad2 = random.randrange(10)
tmp += str(rad2)
else:
# 生成字母对应的 ASCII 码
rad3 = random.randrange(65,91)
tmp += chr(rad3)
print(tmp)

目录和文件操作os

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import os
# 目录的操作
dir_path = "D:\\"
file = [os.path.splitext(dir_path+f) for f in os.listdir(dir_path) if os.path.isfile(dir_path+f)]

# 文件的操作,默认的打开方式是只读的 "r"
f = open("file.txt", "w+")
# 写入数据到文件中
f.writelines("这里是一行数据")
f.close()
f = open("file.txt")
# 读取文件中的数据
print(f.readline())
f.close()

struct模块

1
2
3
4
5
6
7
8
import struct
# 打包: pack int + int + char[1024]
b = struct.pack("ii1024s", 1, 2, b"nihao")
print(b)

# 解包: 提供二进制数据和 fmt,返回一个元组,需要元组解包
i1, i2, s = struct.unpack("ii1024s", b)
print(i1, i2, s)