Day_1
变量 --> 存储, 调用一个东西。
python是一个动态语言, 定义变量不需要声明数据类型。
变量名只能是 字母, 数字或下划线的任意组合。
不可以是数字开口, 不可以有特殊字符。
关键字不能声明为变量名。
变量名要有含义。
在python中没有常量的概念, 但是要表示常量时, 全部变量名要用大写。
PIE = “ ”
name = "Lis"
print("My name is ", name)
# Author : Lis
name = "Lis"
name_2 = name # 通过变量直接指向内存地址, 而不是通过name 找到内存地址。
print("My name is ", name, name_2)
name = "PaoChe Ge"
print(name, name_2)
字符编码
通过字符编码把字符和二进制转换,联系。
索引表。
ASCII码 255 1bytes
---> 1980 gb2312 7xxx
---> 1995 GBK1.0 2w+
---> 2000 GB18030 27xxx
--->unicode 2bytes
---> utf-8 en: 1bytes, zh: 3bytes
Unicode (统一码, 王国码, 单一码) 16位。
utf-8 可变长的
# 单行注释
''' ''' 多行注释, 还可以打印多行, 把注释部分赋值给一个变量,即可。
在python中 单引号和双引号没有区别
用户交互程序
用户输入:
username = input ("username : ")
password = input ("password : ")
print(username, password)
格式化输出, %s表示的为string 一个占位符。
# Author : Lis
username = input ("username : ")
age = input ("age : ")
job = input ("Job : ")
salary = input ("Salary : ")
# %s 为占位符
info = '''
-------info of %s------
Name : %s
Age : %s
Job : %s
Salary : %s
''' % (username, username, age, job, salary)
print(info)
# Author : Lis
username = input("username : ")
age = int(input("age : "))
print(type(age)) # 打印变量类型
job = input("Job : ")
salary = input("Salary : ")
# %s 为占位符
info = '''
-------info of %s------
Name : %s
Age : %d
Job : %s
Salary : %s
''' % (username, username, age, job, salary)
print(info)
格式化输出
# Author : Lis
username = input("username : ")
age = int(input("age : "))
print(type(age)) # 打印变量类型
job = input("Job : ")
salary = input("Salary : ")
# %s 为占位符
info = '''
-------info of %s------
Name : %s
Age : %d
Job : %s
Salary : %s
''' % (username, username, age, job, salary)
info_2 = '''
-------info of {_username}------
Name : {_username}
Age : {_age}
Job : {_job}
Salary : {_salary}
''' .format(_username=username,
_age=age,
_job=job,
_salary=salary)
info_3 = '''
-------info of {0}------
Name : {0}
Age : {1}
Job : {2}
Salary : {3}
''' .format(username, age, job, salary)
print(info_3)
# Author : Lis
import getpass # 密文
username = input("username : ")
#password = input("password : ")
password = getpass.getpass("password : ") # getpass 在pycharm中是不好使的。
print(username, password)
if else 流程
1. if :
else :
2. if :
elif :
.
.
.
else :
# Author : Lis
age_of_oldboy = 56
guess_age = int(input("guess age : "))
if guess_age == age_of_oldboy:
print("yes, you got it. ")
elif guess_age > age_of_oldboy:
print("think smaller... ")
else:
print("think bigger!")
while 循环
# Author : Lis
age_of_oldboy = 56
count = 0
while True:
if count == 3:
break
guess_age = int(input("guess age : "))
if guess_age == age_of_oldboy:
print("yes, you got it. ")
break
elif guess_age > age_of_oldboy:
print("think smaller... ")
else:
print("think bigger!")
count +=1
# Author : Lis
age_of_oldboy = 56
count = 0
guess_age = 0
while guess_age != age_of_oldboy and count != 3:
guess_age = int(input("guess age : "))
if guess_age > age_of_oldboy:
print("think smaller... ")
elif guess_age < age_of_oldboy:
print("think bigger!")
count +=1
while count < 3:
guess_age = int(input("guess age : "))
if guess_age == age_of_oldboy:
print("yes, you got it. ")
break
elif guess_age > age_of_oldboy:
print("think smaller... ")
else:
print("think bigger... ")
count +=1
牛逼版 while循环 while – else
# Author : Lis
age_of_oldboy = 56
count = 0
guess_age = 0
'''
while guess_age != age_of_oldboy and count != 3:
guess_age = int(input("guess age : "))
if guess_age > age_of_oldboy:
print("think smaller... ")
elif guess_age < age_of_oldboy:
print("think bigger!")
count +=1
while count < 3:
guess_age = int(input("guess age : "))
if guess_age == age_of_oldboy:
print("yes, you got it. ")
break
elif guess_age > age_of_oldboy:
print("think smaller... ")
else:
print("think bigger... ")
count +=1
'''
while count < 3:
guess_age = int(input("guess age : "))
if guess_age == age_of_oldboy:
print("yes, you got it. ")
break
elif guess_age > age_of_oldboy:
print("think smaller... ")
else:
print("think bigger... ")
count +=1
else:
print("you have tried too many times... fuck off!!!")
for 循环
continue 是 跳出本次循环进入下一次循环
break 是结束整个循环
# 其中 0 是开始下标, 9是结束下标, 2是步长
for i in range(0, 10 ,2):
print("loop %d"%(i))
# Author : Lis
count = 0
'''
for i in range(0, 10):
if i < 5:
print("loop %d"%(i))
else:
continue
print("hehe ..... ")
'''
for i in range(10):
print("------------------", i)
for j in range(10):
print(j)
if j > 5:
break
本周作业:
作业一 : 博客(完成)
作业二 :编写登陆接口
- 输入用户名和密码 (用户名和密码也应该写在文件中, 实现多用户登陆)
- 认证成功后显示欢迎信息
- 输错三次后锁定 (用python文件调用的接口, 文件处理)
- 注释 : 下次再登陆时, 首先检测用户是否已经被锁定, 应该有两个文件, 一个用户名和密码文件, 一个锁定用户名文件。
作业三:多级菜单
- 三级菜单
- 可依次选择进入各子菜单
- 所需新知识点:列表、字典
流程图!!!! Readme!!!!
# Author : Lis
import os, os.path
username = input("Username : ")
password = input("Password : ")
count_password = 0
count_username = 0
with open('lock.txt', 'r+') as lockFile:
lock_line = lockFile.readlines()
for i in range(len(lock_line)):
lock_line[i] = lock_line[i].rstrip('\n')
if username in lock_line:
print("Sorry, Your account has been locked down...")
else:
with open('user.txt', 'r') as userFile:
user_line = userFile.readlines()
for i in range(len(user_line)):
user_line[i] = user_line[i].rstrip('\n')
while count_password < 3:
if username in user_line:
if password == user_line[user_line.index(username)+1]:
print("Welcome You!!!!")
break
else:
print("Password Error!!!")
password = input("Password : ")
count_password +=1
if count_password == 3:
print("Error too many... lock username...")
lockFile.write('\n'+username)
else:
print("Username Error")
username = input("Username : ")
count_username +=1
else:
print("Error too many... lock username...1111")
userFile.close()
lockFile.close()
# Author : Lis
level_one = ['黑龙江', '北京', '广东']
level_two = {'黑龙江':[1, 2, 3, 4, 5], '北京':[4, 5, 6, 7], '广东':[7, 8, 9, 0]}
print(level_one)
choose = input("Input Your ???")
if choose in level_one:
print(level_two[choose])
else:
print("Error!!!")
Day_two
模块(库)化
标准库: 不需要下载, 可以直接导入。
第三方库: 需要安装才能使用。
# Author : Lis
import sys
'''
#print(sys.path) # 打印环境变量
print(sys.argv) # 打印相对路径
print(sys.argv[2])
'''
import os # 系统交互
# cmd_res = os.system("dir") # 值 直接输出到屏幕上, 输出完了, 就没了。 执行命令, 不保存结果
# cmd_res = os.popen("dir") # 打印结果内存地址
cmd_res = os.popen("dir").read() # 打印结果
print("---->",cmd_res)
os.mkdir("new_dir")
.pyc 文件 是啥?
python和java一样也是基于虚拟机的语言。
PyCodeObject 是python编译器真正编译成的结果。
当python程序运行时, 编译的结果则是保存在位于内存中的PyCodeObject中, 当Python程序运行结束时,Python解释器则将PyCodeObject写回pyc文件中。
当python程序第二次运行时,首先程序会在硬盘中寻找pyc文件, 如果找到,则直接载入, 否则就要重复上面的过程。
pyc文件其实是PyCodeObject的一种持久化保存方式。
python数据类型
1. 数字
2. 字符串
python列表的使用
pop() 删除列表中最后一个元素
append() 追加
sort() 排序(按照ASCII码表排序)
remove() 删除指定元素
extend() 扩展, 由一个列表扩展到另一个列表
insert() 插入
reverse() 反转
index() 索引元素下标
count() 统计元素在列表中的次数
clear() 清空列表
# Author : Lis
names = ["zhangsan", "lisi", "wanger", "liergou", "zhangsan"]
names.append("ershazi") # 追加
names.insert(2, "tudouzi") # 插入 ,想插哪, 就写在哪个位置
print(names.index("wanger"))
print(names.index("zhangsan")) # 获取元素下标
print(names.count("zhangsan")) # 统计次数
print(names)
# 反转
print(names.reverse())
# 排序(按照ASCII码排序)
print(names.sort())
names[2] = "xieding" # 修改
print(names)
names2 = [1, 2, 3]
names.extend(names2) # 扩展
print(names2)
# delete
#names.remove("lisi")
print(names)
del names[3]
print(names)
names.pop()
print(names)
print(names[names.index("zhangsan")])
print(names[1:3]) # 切片
print(names[-1])
print(names[-2])
print(names[-3:-1]) # 从左向右 取 -1 :-3 是不对得。
print(names[-2:])
print(names[:3])
# 清空
print(names.clear())
元组
元组其实跟列表差不多, 也是存一组数, 只不过它一旦创建, 便不能再修改, 所以又叫只读列表。
names = ('zhangsan', 'lisi', 'wanger')
元组只有两个方法, 一个是count, 一个是index。
编程练习
enumerate() 把列表的下标直接取出来。
# Author : Lis
product_list = [
('Iphone', 5800),
('Mac Pro', 9800),
('Bike', 800),
('Watch', 10600),
('Coffee', 31),
('Python', 120)
]
shopping_list = []
salary = input("Input your salary : ")
if salary.isdigit():
salary = int(salary)
while True:
for index, item in enumerate(product_list):
print(index, item)
user_choice = input("选择要买嘛?>>> : ")
if user_choice.isdigit():
user_choice = int(user_choice)
if user_choice < len(product_list) and user_choice >= 0:
p_item = product_list[user_choice]
if p_item[1] <= salary: # 代表买得起
shopping_list.append(p_item)
salary -= p_item[1]
print("Added %s into shopping cart, your current balance is \033[31;1m%s\033[0m"%(p_item, salary))
else:
print("\033[41;1m你的余额只剩[%s]啦, 还买个毛线啊\033[0m"%salary)
else:
print("product code [%s] is not exit!"%user_choice)
elif user_choice == 'q':
print("------------shopping list--------------")
for p in shopping_list:
print(p)
print("Your current balance : ", salary)
exit()
else:
print("invalid option ... ")
字符串的操作
字符串的操作
capitalize() 首字母大写
count() 统计字母出现次数
center() 打印长度50, 不够, 在两端补上
endswith() 判断以什么结尾, 返回True, False
expandtabs(tabsize=30)) 在字符串中写一个/t, 把这个/t转换成多少个空格
find() 找到字符串的下标位置
format() 格式化输出
isalnum() 判断是否为 数字 + 字母
isalpha() 纯英文字符
isdigit() 整数
isidentifier() 判断是否为合法的标识符(变量名)
islower() 小写
isnumeric() 判断是不是数字(用isdigit)
istitle() 判断每个字符串首字母是不是大写
isupper() 判断是不是全为大写
join() 将列表变成字符串, 中间可填充
ljust() 长度。。。,不够再左边补上
rjust() 长度。。。,不够再左边补上
lower() 变小写
upper() 变大写
lstrip() 去掉左边的空格 和 换行
rstrip() 去掉右边的空格 和 换行
strip() 去掉两边的空格 和 换行
replace() 替换
rfind() 从左至右查找, 找到最右边的, 返回下标
split() 按照分隔符, 将字符串转成列表, 默认空格
swapcase() 大小写转换, 大写变成小写, 小写变成大写
# Author : Lis
name = "my name is {_name}, age is {_age}. "
# 首字母大写
print(name.capitalize())
# 统计字母次数
print(name.count("m"))
# 一共打印50个字符, 不够用 - 补上
print(name.center(50, "-"))
# 判断以什么结尾, 返回 True, False
print(name.endswith("ni. "))
# 在字符串中写一个tab键 ,把这个tab键转换成多少个空格
print(name.expandtabs(tabsize=30))
# 找到字符开始位置的索引
print(name.find("name"))
# 格式化输出
print(name.format(_name= 'lis', _age=23))
print(name.format_map( {'_name':'lis', '_age':23} ))
# 阿拉伯数字 + 英语字母(数字 + 字母)
print('abc234'.isalnum())
# 纯英文字符
print('abc'.isalpha())
# 整数
print('100'.isdigit())
# 判断是不是一个合法的标识符(变量名)
print('a1A'.isidentifier())
# 判断是不是一个小写
print('aaaa'.islower())
# 判断是不是一个数字(就用isdigit())
print('33'.isnumeric())
# 每个单词的首字母都大写
print('My Name Is '.istitle())
# 判断是不是全为大写
print('My Name is '.isupper())
# 把列表变成字符串, 中间可填充
print(','.join(['1', '2', '3']))
# 长度50,不够在末尾用 * 补上
print(name.ljust(50, '*'))
# 长度50, 不够在开始用 - 补上
print(name.rjust(50, '-'))
# 大写 变 小写
print('My Name '.lower())
# 小写 变 大写
print('My Name '.upper())
# 从左边去掉 换行 和 回车
print('\nMy Name '.lstrip())
# 从右边去掉 换行 和 回车
print('My Name \n'.rstrip())
# 从两边去掉 换行 和 回车
print('\n My Name \n'.strip())
p = str.maketrans('tlsi', '1234')
print("lis T".translate(p))
# 替换, 第三个参数是 替换第几个(可缺省)
print('list, lis'.replace('l', 'L', 1))
# 从左向右, 找到最右边, 返回下标
print('list'.rfind('i'))
# 将 ‘l’ 当作分割符, 来将字符串转换为列表, 默认为空格
print('list lis'.split('l'))
print('1+2+3+4'.split('+'))
# 大小写转换, 将小写变成大写, 大写变成小写
print('List Lis'.swapcase())
# 不够, 用0填充
print('List Lis'.zfill(50))
字典
字典是一个种 key-value 的数据类型。
字典的特性:
- dict是无序的。
- key必须是唯一的, so 天生去重(重复)
字典可以多级嵌套, 套字典, 套列表。最后形成树型结构。
setdefault
update
items 把字典转成列表
fromkeys() 初始化一个新的字典
# Author : Lis
# key - value
info = {
'stu1001': "Zhang San",
'stu1002': "Li Si",
'stu1003': "Wang ErMaZi",
'stu1004': "Jizhi Tudouni"
}
# 字典是无序的, 因为字典没有下标
print(info)
# 通过key 取value
print(info["stu1001"])
info['stu1004'] = "鸡汁土豆泥"
print(info)
# 如果没有要修改的数据, 则在字典中添加一项
info['stu1005'] = "黑胶牛里脊"
print(info)
print("".center(50,"-"))
# 查找
print(info.get("stu1004"))
# 判断 一个 key 是否在 字典中
print('stu1001' in info)
print("".center(50,"-"))
# 删除
del info['stu1005'] # del 是python内置的方法, 想删谁就删谁
print(info)
info.pop("stu1004")
print(info)
# 随便删一个(二傻子方法!!!)
info.popitem()
for i in info:
print(i, infor[i])
for k, v in items():
print(k, v)
# 第一种方式, 比第二种高效。
Day_3
集合
集合是一个无序的, 不重复的数据组合, 它的主要作用如下:
- 去重, 把一个列表变成集合, 就自动去重了
- 关系测试, 测试两组数据之间的交集, 差集, 并集等关系
intersection 交集 &
union 并集 |
difference 差集 -
issubset 子集
issuperset 父集
symmetric_difference 对称差集 ^
# Author : Lis
list_one = [1, 4, 5, 7, 3, 6, 7, 9]
# 去重, 并变成了集合, 集合也是无序的
list_one = set(list_one)
# 创建一个集合
list_two = set([2, 6, 0, 66, 22, 8, 4])
print(list_one, type(list_one))
print(list_two)
# 交集
print(list_one.intersection(list_two))
# 并集(去掉重复部分)
print(list_one.union(list_two))
# 差集(保留 1 里有 2里没有的)
print(list_one.difference(list_two))
print(list_two.difference(list_one))
# 子集
print(list_one.issubset(list_two))
# 父集
print(list_one.issuperset(list_two))
# 对称差集(把两个里面都没有的取出)
print(list_one.symmetric_difference(list_two))
print("".center(60, "-"))
# 交集
print(list_one & list_two)
# 并集
print(list_one | list_two)
# 差集 in list_one bu not in list_two
print(list_one - list_two)
# 对称差集
print(list_one ^ list_two)
# 添加
list_one.add(999)
list_one.update([111, 222, 333])
print(list_one)
# del
list_one.remove("2")
# 随机删
list_one.pop()
# 删除, 不存在也不会报错
print(list_one.discard("dddd"))
文件读写与详解
对文件操作流程:
1. 打开文件, 得到文件句柄并赋值给一个变量
2. 通过句柄对文件进行操作
3. 关闭文件
r 只读
w 只写(会覆盖)
a 追加(不能读)
r+ 读写(用的最多)
w+ 写读(没什么用)
a+ 追加读
rb 以二进制的形式,读文件(视频, 音频)
wb 以二进制的形式,写文件
tell() 当前光标位置的字符数
readline() 读取一行
readlines() 读取全部
flush() 强制刷新
truncat() 截断,从开始位置截取, 默认清空
seek() 移动光标
为了避免打开文件后忘记关闭, 可以通过管理上下文, 即:
with open('log', 'r') as f:
....
如此方式, 当with代码块执行完毕时, 内部会自动关闭并释放文件资源。
with open('log_one') as obj_one, open('log_two') as obj_two :
pass
# Author : Lis
# 打开文件 (low)
# data = open('yesterday', encoding="utf-8").read()
'''
f = open("yesterday", 'r+', encoding = "utf-8") # 文件句柄
data = f.read()
data_two = f.read()
print(data)
print("".center(60, "-"))
print(data_two)
f.write("年少有位, 不自卑!!!!")
f.close()
'''
# f = open("yesterday", 'r+', encoding="utf-8") # 读写
f = open("yesterday", 'w+', encoding="utf-8") # 写读
# 按照字符计数
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
print(f.tell())
print(f.encoding)
# 编号, 没用
print(f.fileno())
# 刷啥? 强制刷新
print(f.flush())
# 截断 ,默认清空, 从头截断, 移动光标不管用
f.truncate()
# 移动光标
f.seek(0)
print(f.readline())
'''
for line in f.readlines():
print(line.strip())
'''
# high bi ge
# 每次打印, 内存中只保存一行, 把文本变成了迭代器
# for line in f:
# print(line)
# low loop
'''
for index, line in enumerate(f.readlines()):
if index == 9:
print("".center(60, "-"))
continue
print(line.strip())
'''
f.close()
进度条
# Author : Lis
import sys, time
for i in range(20):
sys.stdout.write("#")
sys.stdout.flush()
time.sleep(0.1)
字符编码转换(一个编码折腾你两个小时)
Unicode存储中文或者英文字母 都是占两个字节, 16位。
在ASCII中英文占一个字节, 存不了中文。
utf-8 是在 Unicode基础上的 一个扩展集。
utf-8 是一个可变长的字符编码。
GBK 需要转换为UTF-8 格式流程:
1. 首先通过编码 【decode】转换为Unicode编码
2. 然后通过解码 【encode】转换为UTF-8编码
GBK --> Unicode (decode)
Unicode --> UTF-8 (encode)
在python3中默认的编码都是Unicode
如果已经是Unicode就不需要再解码了。
不管咋的, 两个不同字符集之间的转换都需要经过Unicode。
# -*- coding:gbk -*- # 文件编码
# Author : Lis
s = "你好" # 此处还是Unicode
s_gbk = s.encode("gbk")
print(s_gbk) # gbk
print(s.encode()) # utf-8
gbk_to_utf8 = s_gbk.decode("gbk").encode("utf-8")
print("utf-8", gbk_to_utf8)
函数与函数式编程
编程方式:
1. 面向对象 --> 类 --> class
2. 面向过程 --> 过程 --> def
3. 函数式编程 --> 函数 --> def
函数是逻辑结构化和过程化的一种编程方法。
函数 --> 有返回值
过程 --> 没有返回值的函数
函数三大优点:
1. 代码重用
2. 保持一致性
3. 可扩展性
当一个 函数 / 过程 没有使用 return 显示的定义返回值时, python解释器会隐式的返回 None, 所以在python中即便是过程也可以算作函数。
# Author : Lis
import time
def logger():
time_format = '%Y-%m-%d %X'
time_current = time.strftime(time_format)
with open('a.txt', 'a+', encoding='utf-8') as f:
f.write('%s end action\n' % time_current)
def test_one():
print('int the test_one')
logger()
def test_two():
print('int the test_two')
logger()
def test_three():
print('int the test_three')
logger()
test_one()
test_two()
test_three()
总结:
返回值数量 = 0, 返回 None
返回值数量 = 1, 返回Object
返回值数量 > 1, 返回tuple(元组)
# Author : Lis
def test_one():
print('in the test_one')
def test_two():
print('in the test_two')
return 0
def test_three():
print('in the test_three')
return 1, 'hello', ['adf', 'sdfs'], {'sdf', 'adsf', 3}
one = test_one()
two = test_two()
three = test_three()
print(one)
print(two)
print(three)
形参和实参
形参:形式参数, 不是实际存在的, 是虚拟变量。在定义函数函数体的时候使用形参, 目的是在函数调用时接收实参(实参个数, 类型应与形参一一对应)
实参:实际参数, 调用函数时传给函数的参数, 可以是常量, 变量, 表达式,函数, 传给形参。
区别: 形参是虚拟的, 不占用内存空间, 形参变量只有在被调用时才分配内存单元, 实参是一个变量, 占用内存空间, 数据传送单向, 实参传给形参, 不能形参传给实参。
关键参数是不能写在位置参数前面的
# Author : Lis
# x, y 形参
def test(x, y):
print(x)
print(y)
# 1, 3 实参
test(y=1, x=3) # 关键字调用 与 形参顺序无关
test(1, 3) # 位置调用 与形参一一对应
# 关键参数是不能写在位置参数前面的
test(3, y=2)
默认参数 : 在定义形参的时候, 给形参赋一个默认的值
默认参数特点:
1. 调用函数的时候, 默认参数可有可无, 非必须传递
# Author : Lis
# 默认参数就是, 在定义形参的时候给一个默认的值
def test(x, y=2):
print(x)
print(y)
# test(1)
test(1, 3)
参数组
变量组, 主要是以 *开头, 后面的变量名随便叫
在实参数量不固定的时候可以使用参数组 *变量名
# Author : Lis
# 变量组, 主要是以 *开头, 后面的变量名随便叫
# 在实参数量不固定的时候可以使用参数组 *变量名
def test(*args):
print(args) # 会将传递过来的实参放在一个元组中
test(1, 2, 3, 4, 5)
test(*[1, 2, 3, 4, 5])
# Author : Lis
# 变量组, 主要是以 *开头, 后面的变量名随便叫
# 在实参数量不固定的时候可以使用参数组 *变量名
def test(*args):
print(args) # 会将传递过来的实参放在一个元组中
# test(1, 2, 3, 4, 5)
# test(*[1, 2, 3, 4, 5])
# 位置参数 和 参数组的应用
def test_one(x, *args):
print(x)
print(args)
test_one(1, 2, 3, 4, 5, 6, 7)
print("".center(50, "-"))
# 向形参传递字典
# **kwargs 把N个关键字参数, 转换成字典的方式
def test_two(**kwargs):
print(kwargs)
print(kwargs["name"])
test_two(name='list', age=8)
# 传字典
test_two(**{"name": 'list', "age": 8})
print("".center(50, "-"))
def test_three(name, **kwargs):
print(name)
print(kwargs)
test_three('list', age=18, sex='M')
print("".center(50, "-"))
def test_four(name, age=18, **kwargs): # 参数组一定要放到最后
print(name)
print(age)
print(kwargs)
# test_four('list', sex='m', hobby='tesla')
test_four('list', 3, sex='m', hobby='tesla')
test_four('list', sex='m', hobby='tesla', age=3)
全局变量 与 局部变量
不要使用 global,不应该在函数中修改全局变量。
改了就灰飞烟灭。
# Author : Lis
school = "Oldboy edu"
def change_name(name):
global school # 在函数内声明 全局变量
school = "Mage Linux"
print("before change ", name, school)
# 局部变量只在局部生效, 这个函数就是这个变量的作用域
name = "List"
print("after change ", name)
name = "list"
change_name(name)
print(name)
print(school)
单个的 整数, 字符串 是不能在局部改全局的,
但是, 列表, 字典, 集合, 是可以在局部改全局的。
全局 与 局部变量
在子程序中定义的变量称为局部变量, 在程序一开始定义的变量称为全局变量
全局变量作用域是整个程序, 局部变量的作用域是定义该变量的子程序
当全局变量与局部变量同名时:
在定义局部变量的子程序内, 局部变量起作用, 在其他地方全局变量起作用
# Author : Lis
names = ['张三', '李四', '王二麻子']
def change_name():
names[0] = "鸡汁土豆泥"
print("inside func", names)
change_name()
print(names)
递归
在函数内部, 可以调用其他函数。如果一个函数在内部调用了自己本身, 这个函数就是递归函数。
递归特性:
1. 必须有一个明确的结束条件
2. 每次深入更深一层递归时, 问题规模相比上次递归都应有所减少
3. 递归效率不高, 递归层次过多会导致栈溢出
# Author : Lis
def calc(n):
print(n)
if n>1:
return calc(n/2)
else:
return n
calc(100)
高阶函数:
变量可以指向函数, 函数的参数能接收变量, 那么一个函数就可以接收另一个函数作为参数, 这种函数称之为高阶函数。
# Author : Lis
def add(a, b, f):
return f(a) + f(b)
res = add(3, -6, abs)
print(res)
Day_4
装饰器
本质是函数,(装饰其他函数)就是为了其他函数添加附加功能。
原则:
1. 不能修改被装饰的函数的源代码
2. 不能修改被装饰的函数的调用方式
3. 该怎么运行怎么运行, 被修饰的函数不知道装饰器的存在
实现装饰器知识储备:
1. 函数即 “变量”
2. 高阶函数
3. 嵌套函数
高阶函数 + 嵌套函数 ==> 装饰器
函数就是变量, 定义一个函数体, 就相当于赋值给了函数名。
函数和变量的回收机制相同, 没有引用立马被回收。
python是解释语言, 逐行解释。 只要在调用之前存在了, 就可以使用。
# Author : Lis
# def foo():
# print('in the foo')
# bar()
#
# foo()
# def bar():
# print('in the bar')
#
# def foo():
# print('in the foo')
# bar()
#
# foo()
# def foo():
# print('in the foo')
# bar()
#
# def bar():
# print('in the bar')
#
# foo()
# def foo():
# print('in the foo')
# bar()
# foo()
# def bar():
# print('in the bar')
# 匿名函数
calc = lambda x:x*3
print(calc(3))
高阶函数:
1. 把一个函数名当做实参传给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
2. 返回值中包含函数名(不修改函数的调用方式)
# Author : Lis
import time
#
# 第一个标准
# def bar():
# time.sleep(3)
# print('in the bar')
#
#
# def test_one(func):
# start_time = time.time()
# func() # run bar()
# stop_time = time.time()
# print("the func run time is %s" % (stop_time - start_time))
#
#
# test_one(bar) # bar 就是一个门牌号, 内存地址
#
# func = bar
# func()
# 第二个标准
def bar():
time.sleep(3)
print('in the bar')
def test_two(func):
print(func)
return func
# bar 是内存地址 bar() 是函数返回值
# print(test_two(bar))
bar = test_two(bar)
bar() # run bar
嵌套函数
在一个函数中又定义一个函数
# Author : Lis
def foo():
print('in the foo')
def bar():
print('in the bar')
bar()
foo()
装饰器
# Author : Lis
import time
def timer(func):
def deco():
start_time = time.time()
func() # run teat_one
stop_time = time.time()
print("the func run time is %s "%(stop_time-start_time))
return deco
@timer # 语法糖
def test_one():
time.sleep(3)
print('in the test_one')
@timer
def test_two():
time.sleep(3)
print('in the test_two')
test_one()
test_two()
# test_one 不能加括号哦!!!!
# deco(test_one)
# deco(test_two)
print(timer(test_one))
# test_one = timer(test_one)
# test_one()
# Author : Lis
import time
def timer(func):
def deco(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs) # run teat_one
stop_time = time.time()
print("the func run time is %s " % (stop_time - start_time))
return deco
@timer # 语法糖
def test_one():
time.sleep(3)
print('in the test_one')
@timer
def test_two(*args, **kwargs):
print('test_two : ', args)
test_one()
test_two("list", 22, "List Lis")
装饰器---plus版
# Author : Lis
import time
user, passwd = 'list', '123'
def auth(auth_type):
print("auth func:", auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs):
print("wrappar func args :", *args, **kwargs)
if auth_type == 'local':
username = input("Username : ").strip()
password = input("Password : ").strip()
if user == username and passwd == password:
print("\033[32;1mUser has passed authentication\033[0m")
res = func(*args, **kwargs)
print("atfer".center(60, "-"))
return res
else:
exit("\033[32;1mInvalid username or password \033[0m")
elif auth_type == 'ldap':
print("搞毛线ldap, 啥都不会 。。 。。。 ")
return wrapper
return outer_wrapper
def index():
print("welcome to index page")
@auth(auth_type='local')
def home():
print("welcome to home page")
return "from home"
@auth(auth_type='ldap')
def bbs():
print("welcome to bbs page")
index()
print(home())
bbs()
# Author : Lis
import time
user, passwd = 'list', '123'
def auth(auth_type):
print("auth func:", auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs):
print("wrappar func args :", *args, **kwargs)
if auth_type == 'local':
username = input("Username : ").strip()
password = input("Password : ").strip()
if user == username and passwd == password:
print("\033[32;1mUser has passed authentication\033[0m")
res = func(*args, **kwargs)
print("atfer".center(60, "-"))
return res
else:
exit("\033[32;1mInvalid username or password \033[0m")
elif auth_type == 'ldap':
print("搞毛线ldap, 啥都不会 。。 。。。 ")
return wrapper
return outer_wrapper
def index():
print("welcome to index page")
@auth(auth_type='local')
def home():
print("welcome to home page")
return "from home"
@auth(auth_type='ldap')
def bbs():
print("welcome to bbs page")
index()
print(home())
bbs()
迭代器 与 生成器
生成器(节省大量空间)
在python中, 这种一边循环一边计算的机制, 称为生成器:generator
[ i*2 for i in range(10) ] 列表生成式
( i*i for i in range(10) ) 生成器
只有在调用的时候才会生成相应的数据(只保留当前位置的数据, 只记录当前位置)
只有个一个__next__() 方法
还可以使用函数来实现生成器。
赋值语句:
a, b = b, a+b
t = (b, a+b) # t 是一个tuple
a = t[0]
b = t[1]
# Author : Lis
def fib(max):
n, a, b = 0, 0, 1
while n < max:
# print(b)
# 只需要把 print 写成 yield 就变成了生成器
yield b
a, b = b, a + b
n = n + 1
return 'done' # 异常时打印的消息
f = fib(6)
while True:
try:
x = next(f)
print('g : ', x)
except StopIteration as e:
print("Generator return value : ", e.value)
break
print("start for".center(60, "="))
# for i in f:
# print(i)
#
# print(f.__next__())
#
可以通过生成器实现并行操作
单线程下的并行效果 (协程)
# Author : Lis
import time
def consumer(name):
print("%s 准备吃包子了!!!"%name)
while True:
baozi = yield
print("包子 [%s] 来了, 被 [%s] 吃了!!!"%(baozi, name))
# c = consumer("鸡汁土豆泥")
# c.__next__() # 只是 唤醒
#
# b1 = "韭菜馅"
# c.send(b1) # 传给 yield 唤醒 + 传值
#
# # c.__next__()
# print(c)
def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print("老子开始准备做包子了!!!")
for i in range(10):
time.sleep(1)
print("做了两个包子!!!!")
c.send(i)
c2.send(i)
producer("list")
迭代器(有序的数据流, 惰性计算(走到这一步才算, 走不到就不算))
可以直接作用于for循环的数据类型有以下几种:
一类是 集合数据类型, 如 list , tuple, dict, set, str 等
一类是 generator 包括生成器 和带yield的generator function
这些可以直接作用于for循环的对象统称为 可迭代(可循环) 对象: Iterable
可以使用 isinstance() 判断一个对象是否是 Iterable 对象
* 可以被 next()函数调用并不断返回下一个值得对象称为 迭代器 :Iterator
生成器肯定是一个迭代器, 因为生成器有next()方法
把list, dict, str 等Iterable 变成 Iterator可以使用 iter()函数。
range() 迭代器
# Author : Lis
import time
def consumer(name):
print("%s 准备吃包子了!!!"%name)
while True:
baozi = yield
print("包子 [%s] 来了, 被 [%s] 吃了!!!"%(baozi, name))
# c = consumer("鸡汁土豆泥")
# c.__next__() # 只是 唤醒
#
# b1 = "韭菜馅"
# c.send(b1) # 传给 yield 唤醒 + 传值
#
# # c.__next__()
# print(c)
def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print("老子开始准备做包子了!!!")
for i in range(10):
time.sleep(1)
print("做了两个包子!!!!")
c.send(i)
c2.send(i)
producer("list")
内置方法:
abs() 取绝对值
all()
序列化 :
将内存对象存入文件
反序列化:
将文件中数据加载出来
json 不同语言之间的简单交互。
json 只能处理简单的数据类型。
# Author : Lis
import json
def sayhi(name):
print("hello, ",name)
info = {
'name':'list',
'age':22,
'func':sayhi
}
f = open("test.txt", "w")
print(json.dumps(info))
f.write(json.dumps(info))
f.close()
# Author : Lis
import json
f = open("test.txt", "r")
data = json.loads(f.read())
print(data['age'])
pickle 可以序列化一切对象
模块定义、导入、优化
1. 定义:
模块: 用来从逻辑上组织python代码(变量, 函数, 类, 逻辑: 实现一个功能),本质就是 .py 结尾的python文件(文件名:test.py, 对应的模块名:test)
包: 用来从逻辑上组织模块的, 本质就是一个目录(必须带有一个__init__.py文件)
2. 导入方法
import module_name
import module_name1, modeule_name2
from module_list import *
from module_list import m1, m2, m3
from module_list import logger as logger_list
3. import本质(路径搜索和搜索路径)
导入模块的本质就是把python文件解释一遍
(import test test = 'test.py all code' )
( from test import m1 m1='code' )
import module_name ----> module_name.py ----> module_name.py路径 ----> sys.path
导入包的本质就是执行该包下的__init__.py文件
4. 导入优化
from module_test import test as tt # 给test方法取一个别名
from module_test import test
5. 模块的分类
a. 标准库(内置模块)
b. 开源模块(第三方模块)
c. 自定义模块
标准库:
1. time 和 datetime
在python中,通常有以下几种表示时间的方式:
* 时间戳:
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。(因为 Unix 是在这个时间诞生的。)
* 格式化的时间字符串
* 元组(struct_time)共有九个元素 :
time.struct_time(tm_year=2018, tm_mon=10, tm_mday=26, tm_hour=9, tm_min=13, tm_sec=47, tm_wday=4, tm_yday=299, tm_isdst=0)
dst 时区 0 表示夏令时
strftime("格式", struct_time) --> "格式化的字符串" Y: x.tm_year, m: x.tm_mon
strptime("格式化的字符串", "格式")--> struct_time
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181026112522648.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0Nzk0Mjcz,size_27,color_FFFFFF,t_70)
2. Random(随机 0~1 浮点数)
sys模块 : 能够访问与python解释器紧密相关的变量和函数
os模块:能够访问多个操作系统服务
此处跳过多个内置模块的讲解
Day_6
编程范式:
实现一个任务的方式有很多种不同的方式, 对于这些不同的编程方式的特点进行总结归纳得出来的编程方式类别, 即为编程范式。
不同的编程范式本质上代表对各种类型的任务的不同的解决问题的思路, 对于大多数语言只支持一种编程范式, 当然也有很多语言同时支持多种编程范式。两种最重要的编程范式分别是面向过程编程和面向对象编程。
面向过程编程:
告诉计算机一步一步的该干什么, 来完成任务。一步步从上到下, 从头到尾的解决问题。
基本设计思路就是程序一开始是要着手解决一个大的问题, 然后把一个大问题分解成很多个小问题或子过程, 这些子过程再执行的过程再继续分解知道小问题足够简单到可以在一个小步骤范围内解决。
所以我们认为, 如果只写一些简单的脚本, 用面向过程的方式是极好的, 但如果你要处理的任务是复杂的, 且需要不断迭代和维护的, 那还是用面向对象最方便了。
面向对象:
Object-Oriented Programming(OOP)
OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述, 使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单, 并且可以大大提高开发效率。基于面向对象的程序可以使人更加容易理解代码逻辑。
世界万物, 皆可分类。
世界万物, 皆为对象。
只要是对象, 就肯定属于某种品类。
只要是对象, 就肯定有属性。
《繁殖意愿》
特性
class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性、共同的方法。
object 对象
一个对象即是一个类的实例化后的实例,一个类必须经过实例化后方可再程序中嗲用, 一个类可以实例化多个对象, 每个对象亦可以有不同的属性, 就像人类是指所有人, 每个人是指具体的对象, 人与人之间有共性, 亦有不同。
1. 封装
在类中对数据的赋值、 内部调用对外部用户是透明的, 这使类变成了一个容器, 里面包含着类的数据和方法。
2. 继承
一个类可以派生出子类, 在这个父类里定义的属性, 方法自动被子类继承。
3. 多态
简单说: “一个接口, 多种实现”
原则:
1. 写重复代码是非常不好的低级行为
2. 你写的代码需要经常变更
把一个类变成一个具体对象的过程叫 实例化 (初始化一个类, 也就是造了一个对象)
类写好了, 不初始化, 类也会在内存中存在,
在内存中, 只要没有赋变量名, 就证明此块内存用完就可以销毁。
类实现过程:
给 类 赋值, 类 开辟一个块新的内存, 存入赋值内容, 在此过程中, 同时把实例的对象名当作参数 传递给了类,直接向对象名中存入变量内容, 类把 变量内容的内存地址, 返回给 对象名。
先找实例变量, 找不到,再找类变量
类变量的用途?
大家公用的属性, 节省开销
语法
1. 属性
2. 方法
3. 构造方法
4. 析构函数
在实例释放、销毁的时候执行的, 通常用作一些收尾工作, 如关闭一些数据库链接,关闭打开的临时文件。
私有方法, 私有属性
就是吧, 只能在类中才能调用
类变量
实例变量
# Author : Lis
class Role:
n = 123 # 类变量
name = "我是类name"
def __init__(self, name, role, weapan, life_value=100, money=15000):
# self 就是为了接收 实例化的对象变量名 动态存入
"""构造函数 : 在实例化时,做一些类的初始化的工作"""
self.name = name # 实例变量(静态属性), 作用域 实例本身
self.role = role
self.weapan = weapan
self.__life_value = life_value # 私有属性
self.money = money
def shot(self): # 类的方法, 功能(动态属性)
print("shoting .... ")
def got_shot(self):
self.__life_value -= 50
print("ah......, I got shot ....")
def buy_gun(self, gun_name):
print("%s just bought %s " % (self.name, gun_name))
# 析构方法, 析构函数
def __del__(self):
pass # print(" %s 彻底死了 。。。。。 " % self.name)
def show_status(self):
print("name : %s weapan : %s life_val : %s"%(self.name, self.weapan, self.__life_value))
r1 = Role('List', 'police', 'AK47') # Role(r1, 'List', 'police', 'AK47') 实例化(初始化一个类, 造了一个对象)
r1.buy_gun("Ak47")
r1.got_shot()
print(r1.show_status())
# r1.name = "鸡汁土豆泥"
#
# r1.bullet_prove = True # 额外添加属性
# print(r1.bullet_prove)
#
# print(r1.weapan)
# del r1.weapan # 删除一个属性
#
# r2 = Role('Jack', 'terrorist', 'B22') # 生成一个角色
# r2.name = "黑胶牛里脊"
# r1.n = "改变类变量" # 实际上是, 在r1的内存中, 创建一个变量 n 赋值 改变类变量, 类中的值并没有改变
#
# print(Role.n)
# print(r1.n, r1.name)
# print(r2.n, r2.name)
# """r1.name = "List"
# r1.role = "police"
# r1.weapan = "AK47"""
# r1.got_shot()
# r1.buy_gun("b51") # 实际上是, Role.buy_gun(r1)
#
# Role.n = "ABC"
# print(r1.n, r2.n)
继承:
# Author : Lis
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(" %s is eating ... " % self.name)
def talk(self):
print(" %s is talking ... " % self.name)
def sleep(self):
print(" %s is sleeping ... " % self.name)
class Man(People):
def piao(self):
print(" %s is piaoing ... 20s ... done." % self.name)
def sleep(self):
People.sleep(self)
print(" man is sleeping ")
class Woman(People):
def get_birth(self):
print(" %s is born a baby...." % self.name)
m1 = Man("鸡汁土豆泥", 22)
m1.eat()
m1.piao()
m1.sleep()
w1 = Woman("黑胶牛里脊", 33)
w1.get_birth()
多继承
# Author : Lis
# class People: # 经典类
# 经典类 和 新式类的主要不同 体现在 继承上
class People(object): # 新式类
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(" %s is eating ... " % self.name)
def talk(self):
print(" %s is talking ... " % self.name)
def sleep(self):
print(" %s is sleeping ... " % self.name)
class Relation(object):
def __init__(self):
print(self.name)
def make_friends(self, obj):
print("%s is making friends with %s " % (self.name, obj.name))
class Man(People, Relation):
def __init__(self, name, age, money): # 重构
# 继承父类的属性 的两种方法
# People.__init__(self, name, age)
super(Man, self).__init__(name, age) # 新式类写法
self.money = money
print(" %s 一出生就有%s money " % (self.name, self.money))
def piao(self):
print(" %s is piaoing ... 20s ... done." % self.name)
def sleep(self):
People.sleep(self)
print(" man is sleeping ")
class Woman(People, Relation):
def get_birth(self):
print(" %s is born a baby...." % self.name)
m1 = Man("鸡汁土豆泥", 22, 10)
# m1.eat()
# m1.piao()
# m1.sleep()
w1 = Woman("黑胶牛里脊", 33)
# w1.get_birth()
m1.make_friends(w1)
python2:
经典类是按照深度优先来继承的, 新式类是按广度优先来继承的
python3:
经典类和新式类都是按照广度优先来继承的。
继承顺序 (广度优先)
继承实例
# Author : Lis
# object 基类(祖宗类)
class School(object):
def __init__(self, name, addr):
self.name = name
self.addr = addr
self.students = []
self.teahers = []
self.staffs = []
def enroll(self, stu_obj): # stu_obj 学生实例
print("为学员 %s, 办理注册手续" % stu_obj.name)
self.students.append(stu_obj)
def hire(self, staff_obj):
print("雇佣新员工 %s" % staff_obj.name)
self.staffs.append(staff_obj)
class SchoolMember(object):
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def tell(self):
pass
class Teacher(SchoolMember):
def __init__(self, name, age, sex, salary, course):
super(Teacher, self).__init__(name, age, sex)
self.salary = salary
self.course = course
def tell(self):
print('''
---- info of Teacher : %s ----
Name : %s
Age : %s
Sex : %s
Salary : %s
Course : %s
''' % (self.name, self.name, self.age, self.sex, self.salary, self.course))
def teach(self):
print("%s is teaching course [%s]" % (self.name, self.course))
class Student(SchoolMember):
def __init__(self, name, age, sex, stu_id, grade):
super(Student, self).__init__(name, age, sex)
self.stu_id = stu_id
self.grade = grade
def tell(self):
print('''
---- info of Student : %s ----
Name : %s
Age : %s
Sex : %s
Stu_id : %s
Grade : %s
''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))
def pay_tuition(self, amount):
print("%s has paid tuition for $%s " % (self.name, amount))
school = School("黑龙江大学", "哈尔滨")
t1 = Teacher("王宁", 22, "MF", 200000, "Linux")
t2 = Teacher("二狗子", 22, "M", 3000, "Python")
s1 = Student("鸡汁土豆泥", 20, "MF", 1001, "Python")
s2 = Student("黑胶牛里脊", 56, "F", 1002, "Linux")
t1.tell()
s1.tell()
school.hire(t1)
school.enroll(s1)
school.enroll(s2)
print(school.students)
print(school.staffs)
school.staffs[0].teach()
for stu in school.students:
print(stu.pay_tuition(5000))
多态实例
接口重用, 一种接口, 多种实现
多态性: 是允许你将父对象设置成为和一个或更多的子对象相等的技术, 赋值后, 父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
就是一句话:允许将子类类型的指针赋值给父类类型的指针。
静态方法、类方法、属性方法
静态方法:
只是名义上归类管理, 实际上在静态方法里访问不了类或实例中的任何属性
类方法:
只能访问类变量, 不能访问实例变量
属性方法:
把一个方法变成一个静态属性
# Author : Lis
class Dog(object):
def __init__(self, name):
self.name = name
@staticmethod # 实际上跟类没什么关系了, 现在它只是一个单纯的函数
def eat(self, food):
print("%s is eating %s " % (self.name, food))
d = Dog("鸡汁土豆泥")
# d.eat("包子")
# 类方法
@classmethod
def eat(self):
print("%s is eating %s " % (self.n, "ddd"))
类的特殊成员方法:
__doc__ 表示类的描述信息
类名.__doc__
__module__和__class__
__module__表示当前操作的对象在那个模块, 即:输出模块
__class__表示当前操作的对象的类是什么, 即:输出类
__call__对象后面加括号, 触发执行。
构造方法的执行是由创建对象触发的, 即:对象 = 类名();
而对__call__方法的执行是由对象后加括号触发的,即 :对象() 或 类()
__dict__查看类中或对象中的所有成员
特殊的成员方法 __new__
追溯 你创将的类的类是谁?
类 是由 type类 实例化产生的
类中有一个属性 __metaclass__, 其用来表示该类由 谁 来实例化创建的
第一阶段 : 解释器从上到下执行代码创建Foo类
第二阶段 : 通过Foo类创建obj对象
创建类的方式有两种 :
# Author : Lis
# class Foo(object):
# def __init__(self, name):
# self.name = name
#
#
# f = Foo("鸡汁土豆泥")
#
# print(type(f))
# print(type(Foo))
def func(self):
print("hello %s" % self.name)
def __init__(self, name, age):
self.name = name
self.age = age
Foo = type('Foo', (object,), {'talk': func,
'__init__': __init__})
f = Foo("List", 22)
f.talk()
print(type(Foo))
反射
hasatter(obj, name_str) : 判断一个对象里是否有对应的字符串的方法
getatter(obj, name_str) : 根据字符串去获取obj对象里的对象的方法的内存地址
setatter(obj, name_str) : 通过字符串设置新的属性
hasatter(obj, name_str) : 指定什么就删什么
# Author : Lis
def bulk(self):
print("%s is aoaoaoao ...."%self.name)
class Dog(object):
def __init__(self, name):
self.name = name
def eat(self, food):
print("%s is eating.....%s....." %(self.name,food))
d = Dog("鸡汁土豆泥")
choice = input(">>>>:").strip()
print(hasattr(d, choice))
# print(getattr(d, choice))
# getattr(d, choice)()
if hasattr(d, choice):
func = getattr(d, choice)
func("黑胶牛里脊")
else:
setattr(d, choice, bulk)
d.talk(d)
异常
try :
code
except (Error1, Error2) as e:
print e
except Exception : 抓住所有错误, 不建议用
# Author : Lis
names = ["鸡汁土豆泥", "黑胶牛里脊"]
data = {}
# names[3]
try:
names[3]
data['name']
except Exception as e:
print("出错了 。。。 ",e)
# except (KeyError, IndexError) as e:
# print("没有这个Key", e)
# except IndexError as e:
# print("列表操作错误", e)
# Author : Lis
names = ["鸡汁土豆泥", "黑胶牛里脊"]
data = {}
# names[3]
try:
# names[3]
# data['name']
# open("test.txt")
a = 1
print(a)
except (KeyError, IndexError) as e:
print("没有这个Key", e)
except IndexError as e:
print("列表操作错误", e)
except Exception as e:
print("出错了 。。。 ", e)
else:
print("一切正常")
finally:
print("不管有没有错, 都执行。。。。")
自定义异常
# Author : Lis
# 继承基类异常
class AlexException(Exception):
def __init__(self, msg):
self.message = msg
def __str__(self):
return self.message
try:
raise AlexException("数据库连不上")
except AlexException as e:
print(e)
网络编程Socket
发 send
收 receive
通信协议
TCP/IP
三次握手, 四次断开
UDP
socket (套接字)提供两个方法:
send()
recv()
两个计算机进行通信:
1. ip
2. port(端口65535)
socket 服务端和客户端通信
客户端
# Author : Lis
import socket
client = socket.socket() # 声明socket类型, 同时生成socket链接对象
client.connect(('localhost', 6969))
client.send(b"hello word")
data = client.recv(1024)
print(data.decode())
client.close()
服务端
# Author : Lis
import socket
server = socket.socket()
server.bind(('localhost', 6969)) # 绑定要监听的端口
server.listen() # 监听
print(" 我要开始等电话了 ")
conn, addr = server.accept() # 等电话打进来 conn 是接收电话的实例
# conn就是客户端连过来而在服务器端为其生成的一个连接实例
print(" 电话进来了 ")
data = conn.recv(1024)
print("recv : ", data.decode())
conn.send(data.upper())
server.close()
此处掠过Python网络编程
进程 与 线程
线程 :(一堆指令)
每一个程序的内存是独立的。
进程: qq 要以一个整体的形式暴露给操作系统管理, 里面包含对各种资源的调用,
内存的管理, 网络接口的调用等。。。。
对各种资源管理的集合 就可以成为进程。
线程是操作系统能够进行运算调度的最小单位, 是一串指令的集合。它被包含在进程之中, 是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流, 一个进程中可以并发多个线程, 每条线程并发执行不同的任务。
进程 要操作cpu, 必须先创建一个线程,
所有在同一个进程里的线程是共享同一块内存空间的
线程共享内存空间, 进程的内存是独立的
线程和进程
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。
程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。
这是这样的设计,大大提高了CPU的利用率。
进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。
进程的缺点:
* 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
* 进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。
线程是操作系统能够进行运算调度的最小单位。
它被包含在进程之中,是进程中的实际运作单位。
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
线程的两种启动方式:
- 类继承方式启动(不推荐使用)
# Author : Lis
import threading, time
# 类的方式启动线程
class MyThread(threading.Thread):
def __init__(self, num):
super(MyThread, self).__init__()
self.num = num
def run(self):
print("running task ", self.num)
t1 = MyThread("t1")
t2 = MyThread("t2")
t1.start()
t2.start()
- 直接调用
# Author : Lis
import threading, time
def run(n):
print("task ", n)
time.sleep(2)
# 并行的
# 启动线程的方式
t1 = threading.Thread(target=run, args=("t1",))
t2 = threading.Thread(target=run, args=("t2",))
t1.start()
t2.start()
# run("t1")
# run("t2")
匿名函数
lambda x :x + 1 此时只是一个内存地址
func = lambda x :x + 1 此时可以通过func调用匿名函数(但不这么使用)
lambda 是和其他函数联合使用的。
匿名函数应只实现简单逻辑。