函数参数
可变参数*args
在函数内部,参数*args接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数
# def say_hello(*args):
高阶函数
把函数作为参数传入,这样的函数称为高阶函数
def calc(my_list, op):
total = my_list[0]
for index in range(1, len(my_list)):
total = op(total, my_list[index])
return total
def add(x, y):
return x + y
def mul(x, y):
return x * y
calc函数中的第二个参数也是个函数, 代表二元运算
这样calc函数就不需要跟某一种特定的二元运算耦合在一起
所以calc函数变得通用性更强, 可以由传入的第二个参数来决定执行何种运算
高内聚 低耦合 high cohesion low coupling
一个函数做好一件事, 一个类只做一件事
关键字函数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
def say_hello(**kwargs):
for key in kwargs:
print(key, ':', kwargs[key])
say_hello(**param)
如果希望一个字典作为参数传入,需要打两个*
say_hello(**param)
列表、元组打一个*
命名关键字
# *为分隔符
def bar():
def foo(a, b, c, *, name, age):
print(a + b + c)
print(name, ':', age)
return foo
x = bar()
print(x(2, 4, 1, name='GL', age=23))
类与对象
类的装饰器
属性装饰器用于类的外部通过对象访问类的内部属性
修改器用于类的外部通过对象访问类的内部属性
# 关联装饰器
@record
# 属性装饰器
@property
# 修改器
@pro_name.setter
Python没有从语言层面支持抽象类的概念
我们可以通过abc模块来制造抽象类的效果
在定义类的时候通过指定metaclass=ABCMeta可以将类声明为抽象类
抽象类是不能建立对象的 抽象类存在的意义是专门拿给其他类继承的
abc模块中还有一个包装器abstractmethod
通过这个包装器可以将方法包装为抽象方法 必须要求子类进行重写
多个子类通过重写抽象方法实现了多态
# 强制子类重写方法
# 抽象方法
@abstractmethod
静态方法
只用于类内部而不给对象使用的类内部函数不用self的参数
@staticmethod
def is_valid(a, b, c):
# classmethod传入的第一个参数相当于self
@classmethod
def is_valid(cls, a, b, c):
类之间的关系
线段上有两个点 - has - a - 关联
人使用了房子 - use - a - 依赖
学生是人 - is - a - 继承
继承
继承 - 从已有的类创建新类的过程
提供继承信息的称为父类(超类/基类)
得到继承信息的称为子类(派生类/衍生类)
通过继承我们可以将子类的重复代码抽取的父类中
之类通过继承并复用这些代码来减少重复代码的编写
# 父类
class Person(object):
def __init__(self, name, age):
self._age = age
self._name = name
@property
def name(self):
return self._name
@property
def age(self):
return self._age
def play(self):
print(self.name + ' is playing')
# 子类
class Teacher(Person):
def __init__(self, name, age):
# 父类成员初始化
super().__init__(name, age)
def teach(self):
print(self.name + ' is teaching')
# 方法重写(override) 覆盖/置换/覆写
# 子类在继承父类的方法之后,对方法进行了重新实现
# 给子类对象发送play消息时执行的是子类重写后的新实现
def play(self):
print(self.name + ' is happy playing')
pygame
创建pygame窗口应用的流程:
# 初始化
pygame.init()
# 窗口应用名称
pygame.display.set_caption('Games')
# 创建应用、赋予对象并设置窗口大小
screen = pygame.display.set_mode([640, 640])
# 窗口背景颜色填充
screen.fill([255, 255, 0])
# 刷新窗口
pygame.display.flip()running = True
# 时间响应
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 点击事件相应
elif event.type == pygame.MOUSEBUTTONDOWN:
pass
# 退出pygame
pygame.quit()
文件流
文件的读写
步骤
打开文件 –> 判断大小 –> 分配内存 –> 读取文件 –> 关闭文件
fs1 = open('file_addr', 'r', encoding='utf-8')
content = fs.read()
print(content)
fs1.close()
fs2 = open('file_addr', 'w', encoding='utf-8')
# 写入方法传入参数类型为bytes
fs.write(bytes(content, encoding='utf-8'))
fs2.close()
用with…as… 方法时为上下文环境,不用close
with open('file_addr', 'r', encoding='utf-8') as fs:
异常处理
异常机制 - 处理程序在运行工程中出现的意外状况的手段
因为不是所有的问题都能够在写程序调试程序的时候就能发现
用try expect来捕获异常
try:
pass
except(FileNotFoundError, IOError):
# except可以写多个分别用于处理不同的异常状况
# 如果try中出现了状况就通过except来捕获错误对其进行对应的处理
print('error!')
else:
# 如果没有出状况那么可以把无风险的饭吗放到else中执行
pass
finally:
# 不管程序正常还是异常最后这里的代码一定会执行
# 此处最适合释放外部资源
open参数:
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
读 + + + +
写 + + + + +
创建 + + + +
覆盖 + +
指针在开始 + + + +
指针在结尾 + +
json
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。
JSON 函数
使用 JSON 函数需要导入 json 库:import json。
函数 | 描述 |
---|---|
json.dumps | 将 Python 对象编码成 JSON 字符串 |
json.loads | 将已编码的 JSON 字符串解码为 Python 对象 |
encode | 将 Python 对象编码成 JSON 字符串 |
decode | 将已编码的 JSON 字符串解码为 Python 对象 |
json格式:
# json格式
json1 = {
'name': 'GhostLinc',
'age': 22,
'class': 'Python1801',
'my_guitar': [
{'brand': 'Schecter', 'style': 'Metal'},
{'brand': 'Epiphone', 'style': 'Blues'}
]
}
json.dumps
json.dumps 用于将 Python 对象编码成 json 字符串。
语法:
#编码json 输入文件
yourdict = json.dump(json1, fp)
json.loads
json.loads 用于解码 JSON 数据。该函数返回 Python 字段的数据类型。
#编码json 输入文件
newdict = json.loads(fp)
encode
Python encode() 函数用于将 Python 对象编码成 JSON 字符串。需要导入模块demjson
yourdict = demjson.encode(json1)
decode
Python 可以使用 demjson.decode() 函数解码 JSON 数据。该函数返回 Python 字段的数据类型。
newdict = demjson.decode(json1)
通过网络数据接口获得数据
大部分网络数据结构的输出格式均为json格式
过程
# 获得URL
req1 = urllib.request.Request(host + path + '?' + my_ip)
# 为获得的URL添加header
req1.add_header('Authorization', 'APPCODE ' + appcode)
# 通过URL得到html内容
resp = urllib.request.urlopen(req1)
# 读取内容
dict1 = resp.read()
# 解码成json格式
json1 = json.loads(dict1)