一周知识点
1.函数
1.1函数传参
- 如果我们定义了一个需要传参数的函数且传的参数是一个字典的时候,这时应该在所传入的参数的前面加上**,如果所传的参数是一个列表的时候应该在参数面前加上 * 如下面的程序所示:
def say_hello(**kwargs):
print(kwargs)
if 'name' in kwargs:
print('你好,%s!' % kwargs['name'])
if 'age' in kwargs:
age = kwargs['age']
if age <= 16:
print('你还是个小屁孩')
else:
print('你已经是个大小伙了')
else:
print('请提供个人信息!')
def main():
say_hello(name='骆昊',age=38, qq=12345678)
param = {'name':'张三','age':38}
say_hello(**param)
my_list = [1,2,3,4,5,6]
say_hello(*my_list)
if __name__ == '__main__':
main()
- 对于函数传参这方面,我们还可以通过向函数里面传入一个函数而不是参数,可以写出更通用、应用范围更广的代码。
装饰器
def record(fn):
def wrapper(*args, **kwargs):
print('准备执行%s函数...' % fn.__name__) 在执行被装饰的函数
val = fn(*args, **kwargs) 参数前面加*加是为了将类拆散取其中的值
print('%s函数执行完成' % fn.__name__)
print('反回了%d' % val) 返回被装饰的函数的执行结果
- record 装饰器(装饰函数)的执行语法 让函数在工作过程中做更多额外的操作。
2 面向对象知识进阶
前面章节我们已经学习过如何创建类和对象以及怎样在程序运用他们,为了让面向对象在程序开发中运用的更流畅,我们需要更加深入的学习面向对象。
2.1 参数装饰器
- 通常我们在程序开发中为了避免参数调用冲突的时候,一般会对参数进行装饰,常用的装饰器有@property、@setter,前者是对受保护的参数进行访问,后者是进行修改。比如:
class Teacher(object):
def __init__(self,name,age,job):
self._name = name
self._age = age
self._job = job
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@property
def job(self):
return self._job
@age.setter
def age(self,age):
self._age = age
如果缺少了这些装饰器,我们将运用不了我们所需要的参数数据。所以有了这些装饰器,我们可以更安全的使用自己所需要的数据。
2.2 方法重写
- 方法重写主要有3种类型:覆盖、置换和覆写。
在某些特定的时候,我们需要将父类的方法装饰成抽象方法,从而让子类必须进行方法重写,但是Python没有从语言层面支持抽象类的概念,所以在定义类的时候通过制定metaclass=ABCMeta可以将类声明为抽象类,abc模块中还有一个包装器abstractmethod,通过这个包装器可以将方法包装为抽象方法。
from abc import ABCMeta ,abstractmethod
class Staff(object, metaclass = ABCMeta):
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@abstractmethod
def get_salsry(self):
pass
class Manager(Staff):
def get_salsry(self):
return 15000
class Programmer(Staff):
def __init__(self,name):
super().__init__(name)
self._working_hour = 0
@property
def working_hour(self):
return self._working_hour
@working_hour.setter
def working_hour(self,working_hour):
self._working_hour = working_hour \
if working_hour > 0 else 0
def get_salsry(self):
return 150 * self._working_hour
class Salesman(Staff):
def __init__(self,name,sales = 0):
super().__init__(name)
self._sales =sales
@property
def sales(self):
return self._sales
@sales.setter
def sales(self,sales):
self._sales = sales if sales > 0 else 0
def get_salsry(self):
return 1200 + self._sales * 0.05
def main():
emps = [Manager('张三'),Programmer('李四'),Salesman('王二麻子')]
for emp in emps:
if isinstance(emp,Programmer):
emp.working_hour = int(input('请输入%s本月工作时间:' % emp.name))
elif isinstance(emp,Salesman):
emp.sales = int(input('请输入%s本月销售额' % emp.name))
print('%s本月工资为:¥%.2f元' % (emp.name,emp.get_salsry()))
if __name__ == '__main__':
main()
上述程序中get_salary是一个抽象概念,所以我们用@abstractmethod装饰器将它装饰成了一个抽象对象,这样get_salary只能被继承,无法修改。
2.3 读取与改写文件
- 在程序开发过程中,有时我们需要读取文件与改写文件等操作获取或传输数据,这一系列操作:打开文件 ==》 判断大小 ==》 分配内存 ==》 读取文件 ==》 关闭文件。但是我们也可能在这个阶段出现错误,这就是程序中的异常机制 ——处理程序在运行过程中出现的意外状况的手段 try - except 格式:
def main():
try:# 对打开文件的操作进行保护
with open('文件名','r',encoding = 'utf-8') as fs:
#文件名可写为c:/Users/Administrator/路径
#(在路径前一个.当前文件下路径 两个.上一级文件)
# 括号里没有参数 直接读完content = fs.read()
# print(content)
for line in fs: #一行一行阅读
print(line)
mylist = fs.readlines()
print(mylist) ## 将读取的所有行装入列表中
except (FileExistsError,IOError):
# as+错误地址 FileExisError是打开错误 IOError是读写错误
print('指定的文件无法打开')
print('程序执行结束')
from math import sqrt
def is_prime(n):
assert n > 0
for factor in range(2, int(sqrt (n) + 1)):
if n % factor == 0:
return False
return True if n != 1 else False
def m():
filenames =('a.txt','b.txt','c.txt')
fs_list = []
try:
# 把可能出状况(在执行时有风险)的代码放到try代码块保护执行
for filename in filenames:
fs_list.append(open(filename,'w',encoding='utf-8'))
for number in range(1,10000):
if is_prime(number):
if number < 100:
fs_list[0].write(str(number) + '\n')
elif number < 1000:
fs_list[1].write(str(number) + '\n')
else:
fs_list[2].write(str(number) + '\n')
except IOError: ## except 可以写多个
print('读写文件错误')
finally:
#不管正常与否都会运行 所以此处是最好的释放外部资源的位置
for fs in fs_list:
fs.close()#打开文件一定记得关闭文件(如果是with open就可不写)
print('操作完成')
if __name__ == '__main__':
m()
## 写成json文件用json.dump 读取json文件用json.load
import json #导入json模块
import requests #导入requests包
def ma():
dic ={
'姓名':'张三','age':20,'num':123456
} #一般输入字典或者列表
try: # 尝试打开 避免出错
with open('data.json','r',encoding='utf-8') as ll:
#打开data的json文件并存为ll
yourdic = json.load(ll) #读取json文件的命令是load
print(type(yourdic)) #改写json文件的命令是dump
print(yourdic)
except IOError as e: #将读写错误记为e
print(e)
if __name__ == '__main__':
ma()
def mn():
resp = requests.get('http://api.tianapi.com/meinv/?key=823bf1f177a7b23d804eac748faac7d0&num=10')#获取链接的请求
mydict = json.loads(resp.text) #获取链接地址的文本
for tempdict in mydict['newslist']:#对链接地址进行循环
pic_Url = tempdict['picUrl'] #获取图片链接地址组成列表
resp = requests.get(pic_Url) #发送图片下载的请求
filename = pic_Url[pic_Url.rfind('/')+1:]
#将下载的图片放在一个列表里
try:
with open(filename,'wb') as mm: #打开二进制文件filename存为mm
mm.write(resp.content) #对mm进行改写
except IOError as e: #将错误存为e
print(e)
if __name__ == '__main__':
mn()
3 个人心得
这周的学习基本就是讲面向对象讲得更深入了一点,老师还写了几个小游戏的程序,也是为了让我们理解面向对象对于程序的重要性,我也理解多了一点,但还是不是很透彻,需要花更多的时间和努力才行,下周就要第一阶段测试了,希望在学习新知识的同时,我能理解透彻前面的知识,并牢记住。加油吧,希望能顺利通过测试!