day10总结

  1. 如何定义一个函数?

  2. 函数名的规范。(同变量名规范)

    • 规范

    • 建议

      def change_num():
      pass
  3. 函数的注释,说明函数的作用。

    def encrypt(origin):
    """ 用于数据加密和xxx """
    pass
  4. 定义函数时,参数一般有以下情况(形式参数)

    • 情景1

      def func(a1,a2):
      pass
    • 情景2:

      def func(a1,a2=123):
      pass
    • 情景2:

      def func(*args,**kwargs):
      pass
  5. 函数的返回值,一般用于将函数执行的返回给调用者。

    • 默认返回None

    • 遇到return则函数执行完毕

 练习

# 1. 生成一副扑克牌
card_color_list = ["红桃", "黑桃", "方片", "梅花"]
card_nums = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]  # A
all_card_list = [[color, num] for color in card_color_list for num in card_nums]
​
# 2.洗牌
random.shuffle(all_card_list)
​
# 3.给玩家发牌
...
# 4.判断牌是:豹子?同花顺?顺子?对子?单点?
​
calculate_same_num_rule()
calculate_same_color_rule()
calculate_straight_rule()
...

 

 

作业

请定义一个函数,用于计算一个字符串中字符a出现的次数并通过return返回。

参数,字符串。

返回值,字符串中 a 出现的次数。

 第一题

写函数,判断用户传入的一个值(字符串或列表或元组任意)长度是否大于5,并返回真假。


# 第二题

写函数,接收两个数字参数,返回比较大的那个数字(等于时返回两个中的任意一个都可以)。

# 第三题
写函数,函数接收四个参数分别是:姓名,性别,年龄,学历,然后将这四个值通过"*"拼接起来并追加到一个student_msg.txt文件中。

 第四题

补充代码,实现如下功能:

【位置1】读取文件中的每一行数据,将包含特定关键的数据筛选出来,并以列表的形式返回。

【位置1】文件不存在,则返回None

【位置2】文件不存在,输出 "文件不存在",否则循环输出匹配成功的每一行数据。

def select_content(file_path,key):
    # 补充代码【位置1】

result = select_content("files/xxx.txt","股票")
# 补充代码【位置2】
 第五题

补充代码,实现敏感词替换的功能。

def change_string(origin):
    # 补充代码,将字符串origin中中的敏感词替换为 **,最后将替换好的值返回。 
    data_list = ["苍老师","波多老师","大桥"]
    
text = input("请输入内容:")
result = change_string(text)
print(result)
 第六题

基于函数实现用户认证,要求:

写函数,读取的用户信息并构造为字典(用户信息存放在files/user.xlsx文件中)



# 构造的字典格式如下
user_dict = {
    "用户名":"密码"
    ...
}
用户输入用户名和密码,进行校验。(且密码都是密文,所以,需要将用户输入的密码进行加密,然后再与Excel中的密文密码进行比较)

import hashlib

def encrypt(origin):
    origin_bytes = origin.encode('utf-8')
    md5_object = hashlib.md5()
    md5_object.update(origin_bytes)
    return md5_object.hexdigest()


p1 = encrypt('admin')
print(p1) # "21232f297a57a5a743894a0e4a801fc3"

p2 = encrypt('123123')
print(p2) # "4297f44b13955235245b2497399d7a93"

p3 = encrypt('123456')
print(p3) # "e10adc3949ba59abbe56e057f20f883e"
扩展:密码都不是明文。

注册京东,京东存储:用户名和密码(密文)

登录京东:用户名& 密码。

 


 

day11总结

  1. 函数参数传递的是内存地址。

    • 想重新创建一份数据再传递给参数,可以手动拷贝一份。

    • 特殊:参数是动态参数时,通过*或**传参时,会将数据循环添加到参数中(类似于拷贝一份)

      def fun(*args, **kwargs):
      print(args, kwargs)


      fun(*[11, 22, 33], **{"k1": 1, "k2": 2})
  2. 函数的返回值也是内存地址。(函数执行完毕后,其内部的所有变量都会被销毁,引用计数器为0时,数据也销毁)

    def func():
    name = [11,22,33]
    data = name

    func()
    def func():
    name = [11,22,33]
    return name

    data = func()
    while True:
    print(data)
  3. 当函数的参数有默认值 & 默认值是可变类型 & 函数内部会修改内部元素(有坑)

    # 内部会维护一个列表 [],只要b不传值则始终使用都是这个列表。
    def func(a,b=[]):
    b.append(a)
  4. 定义函数写形式参数时可以使用***,执行函数时也可以使用。

  5. 函数名其实也是个变量,他也可以做列表、字典、集合等元素(可哈希)

  6. 函数名可以被重新赋值,也可以做另外一个函数的参数和返回值。

  7. 掌握 print 和 return的区别,学会分析代码的执行流程。

  8. python是以函数为作用域。

  9. 在局部作用域中寻找某数据时,优先用自己的,自己没有就在上级作用域中寻找。

  10. 基于 global关键字可以在局部作用域中实现对全局作用域中的变量(全局变量)重新赋值。

如何查看一个值得内存地址?

函数的参数传递的是引用(内存地址)还是值(拷贝一份)?

看代码写结果

v1 = {}
v2 = v1
v1["k1"] = 123

print(v1,v2)
看代码写结果

def func(k,v,info={}):
    info[k] = v
    return info

v1 = func(1,2)
print(v1)

v2 = func(4,5,{})
print(v2)

v3 = func(5,6)
print(v3)
看代码写结果

def func(k,v,info={}):
    info[k] = v
    return info

v1 = func(1,2)
v2 = func(4,5,{})
v3 = func(5,6)

print(v1,v2,v3)
简述第5题、第6题的结果为何结果不同。

看代码写结果

def func(*args, **kwargs):
    print(args, kwargs)
    return "完毕"


v1 = func(11, 22, 33)
print(v1)

v2 = func([11, 22, 33])
print(v2)

v3 = func(*[11, 22, 33])
print(v3)

v4 = func(k1=123, k2=456)
print(v4)

v5 = func({"k1": 123, "k2": 456})
print(v5)

v6 = func(**{"k1": 123, "k2": 456})
print(v6)

v7 = func([11, 22, 33], **{"k1": 123, "k2": 456})
print(v7)

v8 = func(*[11, 22, 33], **{"k1": 123, "k2": 456})
print(v8)
看代码写结果

def func(*args,**kwargs):
    prev = "-".join(args)
    
    data_list = []
    for k,v in kwargs.items():
        item = "{}-{}".format(k,v)
        data_list.append(item)
    content = "*".join(data_list)
    
    return prev,content

v1 = func("北京","上海",city="深圳",count=99)
print(v1)

v2 = func(*["北京","上海"],**{"city":"深圳","count":99})
print(v2)
补充代码,实现获取天气信息并按照指定格式写入到文件中。

# 获取天气信息示例
import requests
res = requests.get(url="http://www.weather.com.cn/data/ks/101010100.html")
res.encoding = "utf-8"
weather_dict = res.json()

# 获取的天气信息是个字典类型,内容如下:
print(weather_dict)

"""
{
    'weatherinfo': {
        'city': '北京', 
        'cityid': '101010100', 
        'temp': '18', 
        'WD': '东南风', 
        'WS': '1级', 
        'SD': '17%', 
        'WSE': '1', 
        'time': '17:05', 
        'isRadar': '1', 
        'Radar': 'JC_RADAR_AZ9010_JB', 
        'njd': '暂无实况', 
        'qy': '1011', 
        'rain': '0'
    }
}
"""
import requests


def write_file(**kwargs):
    """将天气信息拼接起来,并写入到文件
    格式要求:
        1. 每个城市的天气占一行
        2. 每行的格式为:city-北京,cityid-101010100,temp-18...
    """
    # 补充代码


def get_weather(code):
    """ 获取天气信息 """
    url = "http://www.weather.com.cn/data/ks/{}.html".format(code)
    res = requests.get(url=url)
    res.encoding = "utf-8"
    weather_dict = res.json()
    return weather_dict


city_list = [
    {'code': "101020100", 'title': "上海"},
    {'code': "101010100", 'title': "北京"},
]

# 补充代码
 

看代码写结果

def func():
    return 1,2,3

val = func()
print( type(val) == tuple )
print( type(val) == list )
看代码写结果

def func(users,name):
    users.append(name)
    print(users)

result = func(['武沛齐','李杰'],'alex')
print(result)
看代码写结果

def func(v1):
    return v1 * 2

def bar(arg):
    return "%s 是什么玩意?" %(arg,)

val = func('')
data = bar(val)
print(data)
看代码写结果

def func(v1):
    return v1* 2

def bar(arg):
    msg = "%s 是什么玩意?" %(arg,)
    print(msg) 

val = func('')
data = bar(val)
print(data)
看代码写结果

def func():
    data = 2 * 2
    return data

data_list = [func,func,func]
for item in data_list:
    v = item()
    print(v)
分析代码,写结果:

def func(handler,**kwargs):
    extra = {
        "code":123,
        "name":"武沛齐"
    }
    kwargs.update(extra)
    return handler(**kwargs)
    

def something(**kwargs):
    return len(kwargs)

def killer(**kwargs):
    key_list = []
    for key in kwargs.keys():
        key_list.append(key)
    return key_list


v1 = func(something,k1=123,k2=456)
print(v1)

v2 = func(killer,**{"name":"武沛齐","age":18})
print(v2)
两个结果输出的分别是什么?并简述其原因。

def func():
    return 123

v1 = [func,func,func,func,]
print(v1)

v2 = [func(),func(),func(),func()]
print(v2)
看代码结果

v1 = '武沛齐'

def func():
    print(v1)
    
func()
func()
看代码结果

v1 = '武沛齐'

def func():
    print(v1)
    
func()
v1 = '老男人'
func()
看代码写结果

NUM_LIST = []
SIZE = 18
def f1():
    NUM_LIST.append(8)
    SIZE = 19
    
def f2():
    print(NUM_LIST)
    print(SIZE)
    
f2()
f1()
f2()
看代码写结果

NUM_LIST = []
SIZE = 18
def f1():
    global NUM_LIST
    global SIZE
    NUM_LIST.append(8)
    SIZE = 19
    
def f2():
    print(NUM_LIST)
    print(SIZE)
    
f2()
f1()
f2()
根据要求实现资源下载器。

启动后,让用户选择专区,每个专区用单独的函数实现,提供的专区如下:

下载 花瓣网图片专区

下载 抖音短视频专区

下载 NBA锦集 专区

在用户选择了某个功能之后,表示进入某下载专区,在里面循环提示用户可以下载的内容选项(已下载过的则不再提示下载) 提醒:可基于全部变量保存已下载过得资源。

在某个专区中,如果用户输入(Q/q)表示 退出上一级,即:选择专区。

在选择专区如果输入Q/q则退出整个程序。

每个专区实现下载的案例如下:

图片

# 可供用户下载的图片如下
image_dict = {
    "1":("吉他男神","https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"),
    "2":("漫画美女","https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"),
    "3":("游戏地图","https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"),
    "4":("alex媳妇","https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"),
}
# 下载图片示例
import request

res = requests.get(
    url="https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz",
    headers={
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
    }
)

with open("alex媳妇.png",mode="wb") as f:
    f.write(res.content)
短视频

# 可供用户下载的短视频如下
video_dict = {
    "1":{"title":"东北F4模仿秀",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"},
    "2":{"title":"卡特扣篮",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"},
    "3":{"title":"罗斯mvp",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"},
}
# 下载视频示例
import requests

res = requests.get(
    url="https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg",
    headers={
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
    }
)
with open('罗斯mvp.mp4', mode='wb') as f:
    f.write(res.content)
 

NBA

# 可供用户下载的NBA视频如下
nba_dict = {
    "1":{"title":"威少奇才首秀三双","url":"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"},
    "2":{"title":"塔图姆三分准绝杀","url":"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"}
}
# 下载示例
import requests

res = requests.get(
    url="https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0",
    headers={
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
    }
)
with open('塔图姆三分准绝杀.mp4', mode='wb') as f:
    f.write(res.content)
 

# 1.如何查看一个值得内存地址?
"""
基于内置函数id来获取,例如:
    addr1 = id("武沛齐")
    addr2 = id([11,22,33,44])
"""

# 2.函数的参数传递的是引用(内存地址)还是值(拷贝一份)?
"""
参数参数默认传递的是引用(内存地址)
"""

# 3.看代码写结果
"""
v1 = {}
v2 = v1
v1["k1"] = 123

print(v1, v2)  # {'k1': 123} {'k1': 123}
"""

# 4.看代码写结果
"""
def func(k, v, info={}):
    info[k] = v
    return info


v1 = func(1, 2)
print(v1)  # {1: 2}

v2 = func(4, 5, {})
print(v2)  # {4: 5}

v3 = func(5, 6)
print(v3)  # {1: 2, 5: 6}
"""

# 5.看代码写结果
"""
def func(k, v, info={}):
    info[k] = v
    return info


v1 = func(1, 2)
v2 = func(4, 5, {})
v3 = func(5, 6)

print(v1, v2, v3)  # {1: 2, 5: 6}   {4: 5}   {1: 2, 5: 6}
"""

# 6. 简述第5题、第6题的结果为何结果不同。
"""
第5题中的 v1和v3变量指向的都是函数内部维护的那个列表的内存地址。
    先print(v1)时,函数内部维护的列表的值当时是{1: 2}
    最后print(v3)时,函数内部维护的列表的值已被修改为{1: 2, 5: 6}

第5题中的 v1和v3变量也是指向的都是函数内部维护的那个列表的内存地址。
    最后再print v1和v3 时,结果就是最终函数内部维护的列表的值,即: {1: 2, 5: 6}
"""

# 7.看代码写结果
"""
def func(*args, **kwargs):
    print(args, kwargs)
    return "完毕"


v1 = func(11, 22, 33)  # (11, 22, 33) {}
print(v1)  # 完毕

v2 = func([11, 22, 33])  # ([11, 22, 33],) {}
print(v2)  # 完毕

v3 = func(*[11, 22, 33])  # (11, 22, 33) {}
print(v3)  # 完毕

v4 = func(k1=123, k2=456)  # () {'k1': 123, 'k2': 456}
print(v4)  # 完毕

v5 = func({"k1": 123, "k2": 456})  # ({'k1': 123, 'k2': 456},) {}
print(v5)  # 完毕

v6 = func(**{"k1": 123, "k2": 456})  # () {'k1': 123, 'k2': 456}
print(v6)  # 完毕

v7 = func([11, 22, 33], **{"k1": 123, "k2": 456})  # ([11, 22, 33],) {'k1': 123, 'k2': 456}
print(v7)  # 完毕

v8 = func(*[11, 22, 33], **{"k1": 123, "k2": 456})  # (11, 22, 33) {'k1': 123, 'k2': 456}
print(v8)  # 完毕
"""

# 8.看代码写结果
"""
def func(*args, **kwargs):
    prev = "-".join(args)
    data_list = []
    for k, v in kwargs.items():
        item = "{}-{}".format(k, v)
        data_list.append(item)
        content = "*".join(data_list)
    return prev, content


v1 = func("北京", "上海", city="深圳", count=99)
print(v1)  # ('北京-上海', 'city-深圳*count-99')

v2 = func(*["北京", "上海"], **{"city": "深圳", "count": 99})
print(v2)  # ('北京-上海', 'city-深圳*count-99')
"""

# 9.补充代码,实现获取天气信息并按照指定格式写入到文件中。【重点讲】
"""
import requests


def write_file(**kwargs):
    data_list = []

    row_dict = kwargs["weatherinfo"]
    for k, v in row_dict.items():
        group = "{}-{}".format(k, v)
        data_list.append(group)
    row_string = ",".join(data_list)

    with open('xxxx.txt', mode='a', encoding="utf-8") as file_object:
        file_object.write("{}\n".format(row_string))


def get_weather(code):
    url = "http://www.weather.com.cn/data/ks/{}.html".format(code)
    res = requests.get(url=url)
    res.encoding = "utf-8"
    weather_dict = res.json()
    return weather_dict


city_list = [
    {'code': "101020100", 'title': "上海"},
    {'code': "101010100", 'title': "北京"},
]

for item in city_list:
    # 101020100
    result_dict = get_weather(item["code"])
    write_file(**result_dict)
"""

# 10.看代码写结果
"""
def func():
    return 1, 2, 3


val = func()
print( type(val) == tuple) # True
print( type(val) == list) # False
print( type(val) == dict) # False
"""
"""
info = {
    "1": [11, 22, 33],
    "2": {'k1': 123, "k2": 456, "k3": "999"}
}
index = input("请输入序号:")
value = info[index]
if type(value) == list:
    print(value[0], value[1], value[2])
elif type(value) == dict:
    print(value['k1'], value['k2'], value['k3'])
"""
# 11.看代码写结果
"""
def func(users, name):
    users.append(name)
    print(users)


result = func(['武沛齐', '李杰'], 'alex')  # # ['武沛齐', '李杰', 'alex']
print(result)  # None
"""

# 12.看代码写结果
"""
def func(v1):
    return v1 * 2


def bar(arg):
    return "%s 是什么玩意?" % (arg,)


val = func('你')
data = bar(val)
print(data) # 你你 是什么玩意?
"""

# 13.看代码写结果
"""
def func(v1):
    return v1 * 2


def bar(arg):
    msg = "%s 是什么玩意?" % (arg,)
    print(msg)


val = func('你')
data = bar(val) # 你你 是什么玩意?
print(data) # None
"""

# 14.看代码写结果
"""
def func():
    data = 2 * 2
    return data

data_list = [func,func,func]

for item in data_list:
    v = item()
    print(v)

# 输出:
# 4  
# 4  
# 4
"""

# 15.分析代码,写结果
"""
def func(handler, **kwargs):
    # handler() -> killer()
    # kwargs = {"name": "武沛齐", "age": 18}
    extra = {
        "code": 123,
        "name": "武沛齐"
    }
    kwargs.update(extra)
    # kwargs = {"name": "武沛齐", "age": 18,"code": 123,}
    return handler(**kwargs)


def something(**kwargs):
    return len(kwargs)


def killer(**kwargs):
    # {"name": "武沛齐", "age": 18,"code": 123,}
    key_list = []
    for key in kwargs.keys():
        key_list.append(key)
    return key_list # ["name","age","code"]


v1 = func(something, k1=123, k2=456)
print(v1)  # 4

v2 = func(killer, **{"name": "武沛齐", "age": 18})
print(v2)  # ["name","age","code"]
"""

# 16.两个结果输出的分别是什么?并简述其原因。
"""
def func():
    return 123


v1 = [func, func, func, func, ]
print(v1)  # 列表,内部元素都是函数(将函数名放在列表的索引位置,函数名代指函数)

v2 = [func(), func(), func(), func()]
print(v2)  # 列表,内部元素都是123(执行函数之后,将函数的返回值放在列表的索引位置)
"""

# 17.看代码结果
"""
v1 = '武沛齐'


def func():
    print(v1)


func()  # 武沛齐
func()  # 武沛齐
"""

# 18.看代码结果
"""
v1 = '武沛齐'


def func():
    print(v1)


func()  # 武沛齐

v1 = '老男人'

func()  # 老男人
"""

# 19.看代码写结果
"""
NUM_LIST = []
SIZE = 18


def f1():
    NUM_LIST.append(8)
    SIZE = 19


def f2():
    print(NUM_LIST)
    print(SIZE)


f2()  # []   18
f1()  # 无任何输出
f2()  # [8]   18
"""

# 20.看代码写结果
"""
NUM_LIST = [11, 22, 33]
SIZE = 18


def f1():
    global NUM_LIST
    global SIZE
    NUM_LIST = "武沛齐"
    SIZE = 19


def f2():
    print(NUM_LIST)
    print(SIZE)


f2()  # [11,22,33] 18
f1()  # 无输出
f2()  # 武沛齐  19
"""

# 21.资源下载器 v1版本【重点讲】
"""
import requests

SELECTED_IMAGE_SET = set()  # 已下载图片ID(序号)
SELECTED_VIDEO_SET = set()
SELECTED_NBA_SET = set()


def download(file_path, url):
    res = requests.get(
        url=url,
        headers={
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
        }
    )
    with open(file_path, mode='wb') as f:
        f.write(res.content)


def download_image():
    total_image_dict = {
        "1": ("吉他男神", "https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"),
        "2": ("漫画美女", "https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"),
        "3": ("游戏地图", "https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"),
        "4": ("alex媳妇", "https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"),
    }
    while True:
        # 构造 1.吉他男神;2.漫画美女;
        text_list = []
        for num, item in total_image_dict.items():
            if num in SELECTED_IMAGE_SET:
                continue
            data = "{}.{}".format(num, item[0])
            text_list.append(data)
        if text_list:
            text = ";".join(text_list)
        else:
            text = "无可下载选项"
        # 输出:1.吉他男神;2.漫画美女;3.游戏地图;4.alex媳妇
        print(text)

        # 返回上一步
        index = input("请输入要选择的序号(Q/q退出):")
        if index.upper() == "Q":
            return

        # 选择序号 3
        if index in SELECTED_IMAGE_SET:
            print("已下载,无法再继续下载,请重新选择!")
            continue

        group = total_image_dict.get(index)
        if not group:
            print("序号不存在,请重新选择")
            continue

        # 下载图片
        file_path = "{}.png".format(group[0])
        download(file_path, group[1])

        # 已下载集合中
        SELECTED_IMAGE_SET.add(index)


def download_video():
    total_video_dict = {
        "1": {"title": "东北F4模仿秀",
              'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"},
        "2": {"title": "卡特扣篮",
              'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"},
        "3": {"title": "罗斯mvp",
              'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"},
    }

    while True:
        text_list = []
        for num, item in total_video_dict.items():
            if num in SELECTED_VIDEO_SET:
                continue
            data = "{}.{}".format(num, item["title"])
            text_list.append(data)
        if text_list:
            text = ";".join(text_list)
        else:
            text = "无可下载选项"
        print(text)
        index = input("请输入要选择的序号(Q/q退出):")
        if index.upper() == "Q":
            return

        if index in SELECTED_VIDEO_SET:
            print("已下载,无法再继续下载,请重新选择!")
            continue

        group = total_video_dict.get(index)
        if not group:
            print("序号不存在,请重新选择")
            continue

        file_path = "{}.mp4".format(group["title"])
        download(file_path, group["url"])

        SELECTED_VIDEO_SET.add(index)


def download_nba():
    total_nba_dict = {
        "1": {"title": "威少奇才首秀三双",
              "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"},
        "2": {"title": "塔图姆三分准绝杀",
              "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"}

    }
    while True:
        text_list = []
        for num, item in total_nba_dict.items():
            if num in SELECTED_NBA_SET:
                continue
            data = "{}.{}".format(num, item["title"])
            text_list.append(data)
        if text_list:
            text = ";".join(text_list)
        else:
            text = "无可下载选项"
        print(text)
        index = input("请输入要选择的序号(Q/q退出):")
        if index.upper() == "Q":
            return

        if index in SELECTED_NBA_SET:
            print("已下载,无法再继续下载,请重新选择!")
            continue

        group = total_nba_dict.get(index)
        if not group:
            print("序号不存在,请重新选择")
            continue

        file_path = "{}.mp4".format(group["title"])
        download(file_path, group["url"])

        SELECTED_NBA_SET.add(index)


print("欢迎使用xxx系统")
func_dict = {
    "1": download_image,
    "2": download_video,
    "3": download_nba
}
while True:
    print("1.花瓣网图片专区;2.抖音短视频专区;3.NBA锦集专区 ")
    choice = input("请选择序号:")
    if choice.upper() == "Q":
        break
    func = func_dict.get(choice)
    if not func:
        print("输入错误,请重新选择!")
        continue
    # 进入专区
    func()
"""

# 21.资源下载器 v2版本
"""
import requests

DB = {
    "1": {
        "area": "花瓣网图片专区",
        "total_dict": {
            "1": ("吉他男神", "https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"),
            "2": ("漫画美女", "https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"),
            "3": ("游戏地图", "https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"),
            "4": ("alex媳妇", "https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"),
        },
        "ext": "png",
        "selected": set()
    },
    "2": {
        "area": "抖音短视频专区",
        "total_dict": {
            "1": {"title": "东北F4模仿秀",
                  'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"},
            "2": {"title": "卡特扣篮",
                  'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"},
            "3": {"title": "罗斯mvp",
                  'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"},
        },
        "ext": "mp4",
        "selected": set()
    },
    "3": {
        "area": "NBA锦集专区",
        "total_dict": {
            "1": {"title": "威少奇才首秀三双",
                  "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"},
            "2": {"title": "塔图姆三分准绝杀",
                  "url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"}
        },
        "ext": "mp4",
        "selected": set()
    },
}


def download(file_path, url):
    res = requests.get(
        url=url,
        headers={
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
        }
    )
    with open(file_path, mode='wb') as f:
        f.write(res.content)


def handler(area_info):
    # 进入专区提醒
    summary = "欢迎进入{}".format(area_info['area'])
    print(summary)

    # 专区中选择下载
    while True:
        text_list = []
        for num, item in area_info['total_dict'].items():
            if num in area_info['selected']:
                continue
            if type(item) == tuple:
                data = "{}.{}".format(num, item[0])
            else:
                data = "{}.{}".format(num, item["title"])
            text_list.append(data)
        if text_list:
            text = ";".join(text_list)
        else:
            text = "无可下载选项"

        print(text)
        index = input("请输入要选择的序号(Q/q退出):")
        if index.upper() == "Q":
            return

        if index in area_info['selected']:
            print("已下载,无法再继续下载,请重新选择!")
            continue

        group = area_info['total_dict'].get(index)
        if not group:
            print("序号不存在,请重新选择")
            continue

        if type(group) == tuple:
            title, url = group
        else:
            title, url = group['title'], group['url']

        file_path = "{}.{}".format(title, area_info['ext'])
        download(file_path, url)

        area_info['selected'].add(index)


print("欢迎使用xxx系统")
while True:
    print("1.花瓣网图片专区;2.抖音短视频专区;3.NBA锦集 专区 ")
    choice = input("请选择序号(Q/q退出):")
    if choice.upper() == "Q":
        break

    # 选择序号: 去db中找对应的字典信息
    area_dict = DB.get(choice)

    if not area_dict:
        print("输入错误,请重新选择!")
        continue

    # 进入专区(area_dict选择的专区信息)
    handler(area_dict)

"""

View Code

 

 

day12总结

  1. 函数可以定义在全局、也可以定义另外一个函数中(函数的嵌套)

  2. 学会分析函数执行的步骤(内存中作用域的管理)

  3. 闭包,基于函数的嵌套,可以将数据封装到一个包中,以后再去调用。

  4. 装饰器

    • 实现原理:基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内层函数),执行函数时再在内层函数中执行闭包中的原函数。

    • 实现效果:可以在不改变原函数内部代码 和 调用方式的前提下,实现在函数执行和执行扩展功能。

    • 适用场景:多个函数系统统一在 执行前后自定义一些功能。

    • 装饰器示例

      import functools


      def auth(func):
      @functools.wraps(func)
      def inner(*args, **kwargs):
      """巴巴里吧"""
      res = func(*args, **kwargs) # 执行原函数
      return res

      return inner

作业

请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:执行func时,先执行func函数内部代码,再输出 "after"

def func(a1):
    return a1 + "傻叉"

def base(a1,a2):
    return a1 + a2 + '傻缺'


def foo(a1,a2,a3,a4):
    return a1 + a2 + a3 + a4 + '傻蛋'
请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。

import random 


def func():
    return random.randint(1,4)

result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result
print(result) 
请为以下函数编写一个装饰器,添加上装饰器后可以实现: 检查文件所在路径(文件件)是否存在,如果不存在自动创建文件夹(保证写入文件不报错)。

def write_user_info(path):
    file_obj = open(path, mode='w', encoding='utf-8')
    file_obj.write("武沛齐")
    file_obj.close()

write_user_info('/usr/bin/xxx/xxx.png')
分析代码写结果:

def get_data():
    scores = []

    def inner(val):
        scores.append(val)
        print(scores)

    return inner


func = get_data()

func(10)
func(20)
func(30)
看代码写结果

name = "武沛齐"


def foo():
    print(name)


def func():
    name = "root"
    foo()


func()
看代码写结果

name = "武沛齐"


def func():
    name = "root"

    def foo():
        print(name)

    foo()


func()
看代码写结果

def func(val):
    def inner(a1, a2):
        return a1 + a2 + val

    return inner


data_list = []

for i in range(10):
    data_list.append(  func(i)   )

print(data_list)
看代码写结果

def func(val):
    def inner(a1, a2):
        return a1 + a2 + val

    return inner


data_list = []

for i in range(10):
    data_list.append(func(i))

v1 = data_list[0](11,22)
v2 = data_list[2](33,11)

print(v1)
print(v2)
 

# ################### 第1题 ###################
"""
import functools


def outer(function):
@functools.wraps(function)
def inner(*args, **kwargs):
# print("before")
res = function(*args, **kwargs) # 执行原函数
print("after")
return res

return inner


@outer
def func(a1):
return a1 + "傻叉"


@outer
def base(a1, a2):
return a1 + a2 + '傻缺'


@outer
def foo(a1, a2, a3, a4):
return a1 + a2 + a3 + a4 + '傻蛋'
"""

# ################### 第2题 ###################
"""
import random
import functools


def five_times(function):
@functools.wraps(function)
def inner(*args, **kwargs):
data_list = []
for i in range(5):
res = function(*args, **kwargs) # 执行原函数
data_list.append(res)
return data_list

return inner


@five_times
def func():
return random.randint(1, 4)


result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result
print(result)
"""

# ################### 第3题 ###################
"""
import os
import functools


def gard(function):
@functools.wraps(function)
def inner(path):

# 获取路径的上级目录
# folder_path = path.rsplit('/', 1)[0]
folder_path = os.path.dirname(path)

# 不存在,就创建
if not os.path.exists(folder_path):
os.makedirs(folder_path)

res = function(path)
return res

return inner


@gard
def write_user_info(path):
file_obj = open(path, mode='w', encoding='utf-8')
file_obj.write("武沛齐")
file_obj.close()


write_user_info('/Users/wupeiqi/PycharmProjects/luffyCourse/day12/xxx.txt')
"""


# ################### 第4~8题 ###################
# 分析过程,请参见视频讲解
def func(val):
def inner(a1, a2):
return a1 + a2 + val

return inner


data_list = []

for i in range(10):
data_list.append(func(i))
# data_list 是inner函数列表
v1 = data_list[0](11, 22) # 11+22+0
v2 = data_list[2](33, 11) # 33+11+2

print(v1)
print(v2)

View Code

 

day13总结

  1. 匿名函数,基于lambda表达式实现一行创建一个函数。一般用于编写简单的函数。

  2. 三元运算,用一行代码实现处理简单的条件判断和赋值。

  3. 生成器,函数中如果yield关键字

    • 生成器函数

    • 生成器对象

    • 执行生成器函数中的代码

      • next

      • for(常用)

      • send

  4. 内置函数(36个)

  5. 推导式

    • 常规操作

    • 小高级操作

作业

看代码写结果

v = [ lambda :x  for x in range(10)] 
print(v)
print(v[0])
print(v[0]())
看代码写结果

v = [i for i in range(10,0,-1) if i > 5]
print(v)
看代码写结果

data = [lambda x:x*i for i in range(10)]
print(data)
print(data[0](2))
print(data[0](2) == data[8](2))
请用列表推导式实现,踢出列表中的字符串,最终生成一个新的列表保存。

data_list = [11,22,33,"alex",455,'eirc']

new_data_list = [ ... ] # 请在[]中补充代码实现。

# 提示:可以用type判断类型
请用列表推导式实现,对data_list中的每个元素判断,如果是字符串类型,则计算长度作为元素放在新列表的元素中;如果是整型,则让其值+100 作为元素放在新的列表的元素中。

data_list = [11,22,33,"alex",455,'eirc']

new_data_list = [ ... ] # 请在[]中补充代码实现。

# 提示:可以基于三元运算实现
请使用字典推导式实现,将如果列表构造成指定格式字典.

data_list = [
    (1,'alex',19),
    (2,'老男',84),
    (3,'老女',73)
]

# 请使用推导式将data_list构造生如下格式:
"""
info_dict = {
    1:(1,'alex',19),
    2:(2,'老男',84),
    3:(3,'老女',73)
}
"""
有4个人玩扑克牌比大小,请对比字典中每个人的牌的大小,并输入优胜者的姓名(值大的胜利,不必考虑A)。

player = {
    "武沛齐":["红桃",10],
    "alex":["红桃",8],
    'eric':["黑桃",3],
    'killy':["梅花",12],
}
尽量多的列举你记得的内置函数?【能记住多少就写多少,不强制去背,在此尽权利写即可,这种公共后续用的多了就自然而然就记住了】

请编写一个生成器函数实现生成n个斐波那契数列的值。

什么是斐波那契数列?

前两个数相加的结果,就是下一个数。
1 1 2 3 5 8 13 21 34 55 ...
代码结构示例,请在此基础上补充代码实现。

def fib(max_count):
    pass


count = input("请输入要生成斐波那契数列的个数:")
count = int(count)
fib_generator = fib(count)
for num in fib_generator:
    print(num) 
 

# 第1题:参考视频的分析过程(也可以自己运行比较结果是否与你分析一致)

# 第2题:参考视频的分析过程(也可以自己运行比较结果是否与你分析一致)

# 第3题:参考视频的分析过程(也可以自己运行比较结果是否与你分析一致)

# 第4题
"""
data_list = [11, 22, 33, "alex", 455, 'eirc']

new_data_list = [item for item in data_list if type(item) == int] # 请在[]中补充代码实现。
print(new_data_list)
"""
# 第5题
"""
data_list = [11, 22, 33, "alex", 455, 'eirc']

new_data_list = [len(item) if type(item) == str else item + 100 for item in data_list]
print(new_data_list)
"""

# 第6题
"""
data_list = [
(1, 'alex', 19),
(2, '老男', 84),
(3, '老女', 73)
]

info_dict = {item[0]: item for item in data_list}
print(info_dict)
"""

# 第7题
"""
player = {
"武沛齐": ["红桃", 10],
"alex": ["红桃", 8],
'eric': ["黑桃", 3],
'killy': ["梅花", 12],
}

winner = sorted(player.items(), key=lambda x: x[1][-1], reverse=True)[0][0]
print(winner)

data = sorted(player.items(), key=lambda x: x[1][1])[-1][0]
print(data)
"""


# 第8题(自己写就好)

# 第9题
def fib(max_count):
first = 1
second = 0
count = 0
while count < max_count:
next_value = first + second
first = second
second = next_value
yield next_value
count += 1


limit_count = input("请输入要生成斐波那契数列的个数:")
limit_count = int(limit_count)
fib_generator = fib(limit_count)
for num in fib_generator:
print(num)

View Code

 

 

 

day14小结

  1. 模块和包的区别

  2. 导入模块的两种方式:

    import xx
    from xxx import xxx
  3. 相对导入,需要有包名称。

  4. 模块重名可以通过as取别名。

  5. 执行py文件时,内部__name__=="__main__",导入模块时,被导入的模块 __name__="模块名"

  6. 在项目开发中,一般在主文件中会写上 main (主文件标记,不是绝对的,因为其他文件在开发调试时候有时候也可能有main)。

 

总结

  1. 模块和包的区别

  2. 了解如何导入模块

    • 路径

    • 导入方式

  3. 导入模块时一般要遵循的规范【补充】

    • 注释:文件顶部或init文件中。

    • 在文件顶部导入

    • 有规则导入,并用空行分割。

      # 先内置模块

      # 再第三方模块

      # 最后自定义模块
      import os
      import sys
      import random
      import hashlib

      import requests
      import openpyxl

      from commons.utils import encrypt
  4. 第三方模块安装的方法

  5. 常见内置模块

 作业:

  1. 自己去网上搜索如何基于Python计算mp4视频的时长,最终实现用代码统计某个文件夹下所有mp4的时长。

 

 

day15总结

  1. json格式和json模块

  2. json模块处理特殊的数据类型

  3. datetime格式与字符串、时间戳以及相关之间的转换。

  4. datetime格式时间与timedelta的加减。

  5. 两个datetime相减可以计算时间间隔,得到的是一个timedelta格式的时间。

  6. 了解正则表达式的编写方式和python中re模块的使用。

  7. 项目开发规范。

练习题

日志记录,将用户输入的信息写入到文件,文件名格式为年-月-日-时-分.txt。

from datetime import datetime

while True:
    text = input("请输入内容:")
    if text.upper() == "Q":
        break
        
    current_datetime = datetime.now().strftime("%Y-%m-%d-%H-%M")
    file_name = "{}.txt".format(current_datetime)
    
    with open(file_name, mode='a', encoding='utf-8') as file_object:
        file_object.write(text)
        file_object.flush()
用户注册,将用户信息写入Excel,其中包含:用户名、密码、注册时间 三列。

import os
import hashlib
from datetime import datetime

from openpyxl import load_workbook
from openpyxl import workbook


BASE_DIR = os.path.dirname(os.path.abspath(__file__))
FILE_NAME = "db.xlsx"


def md5(origin):
    hash_object = hashlib.md5("sdfsdfsdfsd23sd".encode('utf-8'))
    hash_object.update(origin.encode('utf-8'))
    return hash_object.hexdigest()


def register(username, password):
    db_file_path = os.path.join(BASE_DIR, FILE_NAME)
    if os.path.exists(db_file_path):
        wb = load_workbook(db_file_path)
        sheet = wb.worksheets[0]
        next_row_position = sheet.max_row + 1
    else:
        wb = workbook.Workbook()
        sheet = wb.worksheets[0]
        next_row_position = 1

    user = sheet.cell(next_row_position, 1)
    user.value = username

    pwd = sheet.cell(next_row_position, 2)
    pwd.value = md5(password)

    ctime = sheet.cell(next_row_position, 3)
    ctime.value = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    wb.save(db_file_path)


def run():
    while True:
        username = input("请输入用户名:")
        if username.upper() == "Q":
            break
        password = input("请输入密码:")
        register(username, password)


if __name__ == '__main__':
    run()

View Code

作业:开发短视频资讯平台

有video.csv视频库文件,其中有999条短视频数据,格式如下:【 video.csv 文件已为大家提供好,在day15课件目录下。 】

image-20210105223331765

项目的核心功能有:

分页看新闻(每页显示10条),提示用户输入页码,根据页码显示指定页面的数据。

提示用户输入页码,根据页码显示指定页面的数据。

当用户输入的页码不存在时,默认显示第1页

搜索专区

用户输入关键字,根据关键词筛选出所有匹配成功的短视频资讯。

支持的搜索两种搜索格式:

id=1715025,筛选出id等于1715025的视频(video.csv的第一列)。

key=文本,模糊搜索,筛选包含关键字的所有新闻(video.csv的第二列)。

下载专区

用户输入视频id,根据id找到对应的mp4视频下载地址,然后下载视频到项目的files目录。

视频的文件名为:视频id-年-月-日-时-分-秒.mp4

视频下载代码示例

import requests

res = requests.get(
    url='https://video.pearvideo.com/mp4/adshort/20210105/cont-1715046-15562045_adpkg-ad_hd.mp4'
)

# 视频总大小(字节)
file_size = int(res.headers['Content-Length'])

download_size = 0
with open('xxx.mp4', mode='wb') as file_object:
    # 分块读取下载的视频文件(最多一次读128字节),并逐一写入到文件中。 len(chunk)表示实际读取到每块的视频文件大小。
    for chunk in res.iter_content(128):
        download_size += len(chunk)
        file_object.write(chunk)
        file_object.flush()
        message = "视频总大小为:{}字节,已下载{}字节。".format(file_size, download_size)
        print(message)
    file_object.close()

res.close()
下载的过程中,输出已下载的百分比,示例代码如下:

import time

print("正在下载中...")
for i in range(101):
    text = "\r{}%".format(i)
    print(text, end="")
    time.sleep(0.2)

print("\n下载完成")
 

 

附赠
自动采集梨视频1000条资讯的爬虫脚本。梨视频平台系统更新后可能会导致下载失败,到时候需根据平台调整再来修改代码。

"""
下载梨视频的:视频ID,视频标题,视频URL地址 并写入到本次 video.csv 文件中。

运行此脚本需要预先安装:
    pip install request
    pip install beautifulsoup4

"""
import requests
from bs4 import BeautifulSoup


def get_mp4_url(video_id):
    data = requests.get(
        url="https://www.pearvideo.com/videoStatus.jsp?contId={}".format(video_id),
        headers={
            "Referer": "https://www.pearvideo.com/video_{}".format(video_id),
        }
    )
    response = data.json()
    image_url = response['videoInfo']['video_image']
    video_url = response['videoInfo']['videos']['srcUrl']
    middle = image_url.rsplit('/', 1)[-1].rsplit('-', 1)[0]
    before, after = video_url.rsplit('/', 1)
    suffix = after.split('-', 1)[-1]
    url = "{}/{}-{}".format(before, middle, suffix)
    return url


def download_video():
    file_object = open('video.csv', mode='w', encoding='utf-8')
    count = 0
    while count <= 999:
        res = requests.get(
            url="https://www.pearvideo.com/category_loading.jsp?reqType=14&categoryId=&start={}".format(count)
        )
        bs = BeautifulSoup(res.text, 'lxml')
        a_list = bs.find_all("a", attrs={'class': "vervideo-lilink"})
        for tag in a_list:
            title = tag.find('div', attrs={'class': "vervideo-title"}).text.strip()
            video_id = tag.get('href').split('_')[-1]
            mp4_url = get_mp4_url(video_id)
            row = "{},{},{}\n".format(video_id, title, mp4_url)
            file_object.write(row)
            file_object.flush()
            count += 1
            message = "已下载{}个".format(count)
            print(message)
    file_object.close()


if __name__ == '__main__':
    download_video()

View Code

 

day17总结

  1. 类和对象的关系。

  2. 面向对象编程中常见的成员:

    • 绑定方法

    • 实例变量

  3. self到底是什么?

  4. 面向对象的三大特性。

  5. 面向对象的应用场景

    1. 数据封装。

    2. 封装数据 + 方法再对数据进行加工处理。

    3. 创建同一类的数据且同类数据可以具有相同的功能(方法)。

  6. 补充:在Python3中编写类时,默认都会继承object(即使不写也会自动继承)。

    class Foo:
       pass

    class Foo(object):
       pass

    这一点在Python2是不同的:

    • 继承object,新式类

    • 不继承object,经典类

 

 作业

 

简述面向对象三大特性?

将以下函数改成类的方式并调用 :

def func(a1):   
    print(a1) 
面向对象中的self指的是什么?

以下代码体现 向对象的什么特性?

class Person(object):
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
​
​
obj = Person('武沛齐', 18, '')
以下代码体现 向对象的 么特点?

class Message(object):
    def email(self):
        """
        发送邮件
        :return:
        """
        passdef msg(self):
        """
        发送短信
        :return:
        """
        passdef wechat(self):
        """
        发送微信
        :return:
        """
        pass
看代码写结果

class Foo:
    def func(self):
        print('foo.func')
        
obj = Foo()
result = obj.func()
print(result)
看代码写结果

class Base1:
    def f1(self):
        print('base1.f1')

    def f2(self):
        print('base1.f2')

    def f3(self):
        print('base1.f3')
        self.f1()


class Base2:
    def f1(self):
        print('base2.f1')


class Foo(Base1, Base2):
    def f0(self):
        print('foo.f0')
        self.f3()


obj = Foo()
obj.f0()
看代码写结果:

class Base:
    def f1(self):
        print('base.f1')

    def f3(self):
        self.f1()
        print('base.f3')


class Foo(Base):
    def f1(self):
        print('foo.f1')

    def f2(self):
        print('foo.f2')
        self.f3()


obj = Foo()
obj.f2()
补充代码实现

user_list = []
while True:
    user = input("请输入用户名:")
    pwd = input("请输入密码:")
    email = input("请输入邮箱:")
    
"""
# 需求
1. while循环提示 户输 : 户名、密码、邮箱(正则满足邮箱格式)
2. 为每个用户创建一个个对象,并添加到user_list中。
3. 当列表中的添加 3个对象后,跳出循环并以此循环打印所有用户的姓名和邮箱
"""
补充代码:实现 户注册和登录。

class User:
    def __init__(self, name, pwd):
        self.name = name
        self.pwd = pwd


class Account:
    def __init__(self):
        # 用户列表,数据格式:[user对象,user对象,user对象]
        self.user_list = []

    def login(self):
        """
        用户登录,输入用户名和密码然后去self.user_list中校验用户合法性
        :return:
        """
        pass

    def register(self):
        """
        用户注册,没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
        :return:
        """
        pass

    def run(self):
        """
        主程序
        :return:
        """
        pass


if __name__ == '__main__':
    obj = Account()
    obj.run()
 

# 1. 简述面向对象三大特性?
"""
- 封装,将方法封装到类中 或 将数据封装到对象中,便于以后使用。
- 继承,将类中的公共的方法提取到基类中去实现。
- 多态,Python默认支持多态(这种方式称之为鸭子类型),最简单的基础下面的这段代码即可。
def func(arg):
v1 = arg.copy() # 浅拷贝
print(v1)
"""

# 2.将以下函数改成类的方式并调用
"""
class Foo(object):

def func(self, a1):
print(a1)


obj = Foo()
obj.func("武沛齐")
"""

# 3. 面向对象中的self指的是什么?
"""
self是一个参数,在通过 对象.方法 的方式去执行方法时,这个参数会被python自动传递(值为调用当前方法的对象)
"""

# 4.以下代码体现 向对象的什么特性?
"""
封装
"""

# 5. 以下代码体现 向对象的什么特性?
"""
封装
"""

# 6. 看代码写结果
"""
foo.func
None
"""

# 7. 看代码写结果
"""
foo.f0
base1.f3
base1.f1
"""

# 8. 看代码写结果
"""
foo.f2
foo.f1
base.f3
"""

# 9. 补充代码实现
"""
import re


class UserInfo(object):
def __init__(self, name, pwd, email):
self.name = name
self.pwd = pwd
self.email = email


def run():
user_list = []
while True:
user = input("请输入用户名:")
pwd = input("请输入密码:")
email = input("请输入邮箱:")
match_object = re.match("(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)", email, re.ASCII)
if not match_object:
print("邮箱格式输入错误,请重新输入!")
continue

user_object = UserInfo(user, pwd, email)
user_list.append(user_object)
if len(user_list) == 3:
break

for item in user_list:
print(item.name, item.email)


if __name__ == '__main__':
run()
"""


# 10. 补充代码实现

class User:
def __init__(self, name, pwd):
self.name = name
self.pwd = pwd


class Account:
def __init__(self):
# 用户列表,数据格式:[user对象,user对象,user对象]
self.user_list = []

def login(self):
"""
用户登录,输入用户名和密码然后去self.user_list中校验用户合法性
:return:
"""
print("用户登录")
while True:
user = input("请输入用户名(Q/q):")
if user.upper() == 'Q':
break
pwd = input("请输入密码:")

for user_object in self.user_list:
if user == user_object.name and pwd == user_object.pwd:
print("登录成功")
break
else:
print("登录失败")

def register(self):
"""
用户注册,没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
:return:
"""
print("用户注册")
while True:
user = input("请输入用户名(Q/q):")
if user.upper() == 'Q':
break
pwd = input("请输入密码:")
user_object = User(user, pwd)
self.user_list.append(user_object)

def run(self):
"""
主程序
:return:
"""

method_dict = {
"1": {"title": "登录", "method": self.login},
"2": {"title": "注册", "method": self.register},
}
message = ";".join(["{}.{}".format(k, v['title']) for k, v in method_dict.items()])

while True:
print(message)
choice = input("请选择功能(Q/q):")
if choice.upper() == 'Q':
break
info = method_dict.get(choice)
if not info:
print("选择错误,请重新选择")
continue
method = info['method']
method() # self.login() / self.register()


if __name__ == '__main__':
obj = Account()
obj.run()

View Code

练习

class Base:
    def f1(self):
        print('base.f1')
        
class Foo(Base):
    def f2(self):
        print('foo.f2')
        
obj = Foo()
obj.f1()
obj.f2()
 

class Base:
    def f1(self):
        print('base.f1')
        
class Foo(Base):
    def f2(self):
        print('before')
        self.f1() # 调用了f1方法   obj.f1()
        print('foo.f2')
        
obj = Foo()
obj.f2()
​
>>> before
>>> base.f1
>>> foo.f2
 

class Base:
    def f1(self):
        print('base.f1')
        
class Foo(Base):
    def f2(self):
        print("before")
        self.f1() # obj,Foo类创建出来的对象。 obj.f1
        print('foo.f2')
    def f1(self):
        print('foo.f1')
        
obj = Foo()
obj.f1() # obj对象到底是谁?优先就会先去谁里面找。
obj.f2()
​
>>> before
>>> foo.f1
>>> foo.f2
 

class Base:
    def f1(self):
        print('before')
        self.f2() # slef是obj对象(Foo类创建的对象) obj.f2
        print('base.f1')
        
    def f2(self):
        print('base.f2')
        
class Foo(Base):
    def f2(self):
        print('foo.f2')
        
obj = Foo()
obj.f1() # 优先去Foo类中找f1,因为调用f1的那个对象是Foo类创建出来的。
​
​
>>> before
>>> foo.f2
>>> base.f1
​
b1 = Base()
b1.f1()
​
>>> before
>>> base.f2
>>> base.f1
 

class TCPServer:
    def f1(self):
        print("TCPServer")

class ThreadingMixIn:
    def f1(self):
        print("ThreadingMixIn")

class ThreadingTCPServer(ThreadingMixIn, TCPServer): 
    def run(self):
        print('before')
        self.f1()
        print('after')
        
obj = ThreadingTCPServer()
obj.run()

>>> before
>>> ThreadingMixIn
>>> after
 

class BaseServer:
    def serve_forever(self, poll_interval=0.5):
        self._handle_request_noblock()
    def _handle_request_noblock(self):
        self.process_request(request, client_address)
        
    def process_request(self, request, client_address):
        pass
    
class TCPServer(BaseServer):
    passclass ThreadingMixIn:
    def process_request(self, request, client_address):
        pass
    
class ThreadingTCPServer(ThreadingMixIn, TCPServer): 
    pass
​
obj = ThreadingTCPServer()
obj.serve_forever()

View Code

 

 

day18总结

  1. 面向对象编程中的成员

    • 变量

      • 实例变量

      • 类变量

  • 方法 – 绑定方法 – 类方法 – 静态方法

    • 属性

  1. 成员修饰符

  2. 对象中的数据嵌套

  3. 特殊成员

  4. 重要概念:

    • 迭代器

    • 生成器

    • 可迭代对象

 

 

作业

列举面向对象的成员并简述他们的特点。

@staticmethod 和 @classmethod的作用是什么?

面向对象中如何让成员变为私有。

__new__方法的作用?

简述你理解的:迭代器、生成器、可迭代对象。

看代码写结果

class Foo(object):
    a1 = 1
    
    def __init__(self,num):
        self.num = num
        
    def show_data(self):
        print(self.num+self.a1)
    
obj1 = Foo(666)
obj2 = Foo(999)

print(obj1.num)
print(obj1.a1)

obj1.num = 18
obj1.a1 = 99

print(obj1.num)
print(obj1.a1)

print(obj2.a1)
print(obj2.num)
print(obj2.num)
print(Foo.a1)
print(obj1.a1)
看代码写结果,注意返回值。

class Foo(object):
    
    def f1(self):
        return 999
    
    def f2(self):
        v = self.f1()
        print('f2')
        return v
    
    def f3(self):
        print('f3')
        return self.f2()
    
    def run(self):
        result = self.f3()
        print(result)

obj = Foo()
v1 = obj.run()
print(v1)
看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】

class Foo(object):
    
    def f1(self):
        print('f1')

    @staticmethod
    def f2():
        print('f2')
        
obj = Foo()
obj.f1()
obj.f2()

Foo.f1()
Foo.f2()
看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】

class Foo(object):
    
    def f1(self):
        print('f1')
        self.f2()
        self.f3()

    @classmethod
    def f2(cls):
          print('f2')

    @staticmethod
    def f3():
          print('f3')

obj = Foo()
obj.f1()
看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】

class Base(object):
    @classmethod
    def f2(cls):
          print('f2')

    @staticmethod
    def f3():
          print('f3')

class Foo(Base):
    def f1(self):
        print('f1')
        self.f2()
        self.f3()

obj = Foo()
obj.f1()
看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】

class Foo(object):
    a1 = 1
    __a2 = 2
    
    def __init__(self,num):
        self.num = num
        self.__salary = 1000
        
     def show_data(self):
         print(self.num+self.a1)
    
obj = Foo(666)

print(obj.num)
print(obj.a1)
print(obj.__salary)
print(obj.__a2)
print(Foo.a1)
print(Foo.__a2)
obj.show_data()
看代码写结果

class Foo(object):

    def __init__(self, age):
        self.age = age

    def display(self):
        print(self.age)


data_list = [Foo(8), Foo(9)]
# print(data_list[0].age)
# data_list[1].display()

for item in data_list:
    print(item.age, item.display()) 
看代码写结果

class Base(object):
    def __init__(self, a1):
        self.a1 = a1

    def f2(self, arg):
        print(self.a1, arg)


class Foo(Base):
    def f2(self, arg):
        print('666')


obj_list = [Base(1), Foo(2), Foo(3)]

for item in obj_list:
    item.f2(1)
看代码写结果

class Foo(object):
    def __init__(self, num):
        self.num = num
        
v1 = [Foo for i in range(10)]
v2 = [Foo(5) for i in range(10)]
v3 = [Foo(i) for i in range(10)]

print(v1)
print(v2)
print(v3)
看代码写结果

class StarkConfig(object):

    def __init__(self, num):
        self.num = num

    def changelist(self, request):
        print(self.num, request)


config_obj_list = [ StarkConfig(1),  StarkConfig(2),  StarkConfig(3) ]
for item in config_obj_list:
    print(item.num)
看代码写结果

class StarkConfig(object):

    def __init__(self, num):
        self.num = num

    def changelist(self, request):
        print(self.num, request)


config_obj_list = [StarkConfig(1), StarkConfig(2), StarkConfig(3)]
for item in config_obj_list:
    item.changelist(666)
看代码写结果

class StarkConfig(object):

    def __init__(self, num):
        self.num = num

    def changelist(self, request):
        print(self.num, request)

    def run(self):
        self.changelist(999)


class RoleConfig(StarkConfig):

    def changelist(self, request):
        print(666, self.num)


class AdminSite(object):
    def __init__(self):
        self._registry = {}

    def register(self, k, v):
        self._registry[k] = v


site = AdminSite()

site.register('武沛齐', StarkConfig(19))
site.register('root', StarkConfig(20))
site.register("admin", RoleConfig(33))

print(len(site._registry))

for k, row in site._registry.items():
    row.changelist(5)
看代码写结果(如有报错,请标注报错位置)

class StarkConfig(object):
    def __init__(self, num):
        self.num = num
    def run(self):
        self()
    def __call__(self, *args, **kwargs):
        print(self.num)
        
class RoleConfig(StarkConfig):
    def __call__(self, *args, **kwargs):
        print(345)
    def __getitem__(self, item):
        return self.num[item]
    
v1 = RoleConfig('alex')
v2 = StarkConfig("wupeiqi")

print(v1[1])
print(v2[2])
补全代码

class Context:
    pass


with Context() as ctx:
    ctx.do_something()
看代码写结果

class Department(object):
    def __init__(self,title):
        self.title = title

class Person(object):
    def __init__(self,name,age,depart):
        self.name = name
        self.age = age 
        self.depart = depart
    
    def message(self):
        msg = "我是%s,年龄%s,属于%s" %(self.name,self.age,self.depart.title)
        print(msg)
    
    
d1 = Department('人事部')
d2 = Department('销售部')

p1 = Person('武沛齐',18,d1)
p2 = Person('alex',18,d1)

p1.message()
p2.message()
分析代码关系,并写出正确的输出结果。

class Node(object):
    def __init__(self, title):
        self.title = title
        self.children = []

    def add(self, node):
        self.children.append(node)

    def __getitem__(self, item):
        return self.children[item]


root = Node("中国")

root.add(Node("河南省"))
root.add(Node("河北省"))

print(root.title)
print(root[0])
print(root[0].title)
print(root[1])
print(root[1].title)
 

分析代码关系,并写出正确的输出结果。

class Node(object):
    def __init__(self, title):
        self.title = title
        self.children = []

    def add(self, node):
        self.children.append(node)

    def __getitem__(self, item):
        return self.children[item]


root = Node("中国")

root.add(Node("河南省"))
root.add(Node("河北省"))
root.add(Node("陕西省"))
root.add(Node("山东省"))

root[1].add(Node("石家庄"))
root[1].add(Node("保定"))
root[1].add(Node("廊坊"))

root[3].add(Node("潍坊"))
root[3].add(Node("烟台"))
root[3].add(Node("威海"))

root[1][1].add(Node("雄安"))
root[1][1].add(Node("望都"))

print(root.title)
print(root[0].title)
print(root[1].title)
print(root[1][0].title)
print(root[1][2].title)
print(root[1][1][0].title)
 

 

# 1. 列举面向对象的成员并简述他们的特点。
"""
- 变量
- 实例变量,属于对象。每个对象中中都封装各自的值。只能通过的对象来进行调用。
- 类变量,属于类。每个类中各自保存的数据。可以通过对象和类来进行读取。
- 方法
- 绑定方法,默认有一个self参数,由对象进行调用(此时self就等于调用方法的这个对象)【对象&类均可调用】
- 类方法,默认有一个cls参数,用类或对象都可以调用(此时cls就等于调用方法的这个类)【对象&类均可调用】
- 静态方法,无默认参数,用类和对象都可以调用。【对象&类均可调用】
- 属性
基于方法+property装饰器实现可以实现,可以实现
obj.属性名
obj.属性名 = 123
del obj.属性名
语法和方法的对应关系。
"""

# 2. @staticmethod 和 @classmethod的作用是什么?
"""
@classmethod,将一个方法变换类方法;类和方法都可以调用,且cls默认是当前执行该方法的类。
@staticmethod,将一个方法变换为静态方法,静态方法的调用可以是类也可以对象,无默认参数。
"""

# 3. 面向对象中如何让成员变为私有。
"""
前面加上 __
"""

# 4. `__new__`方法的作用?
"""
__new__是构造方法,用于创建对象(空对象),在__init__方法执行之前。
"""

# 5. 简述你理解的:迭代器、生成器、可迭代对象。
"""
迭代器,含有__iter__方法和__next__方法,__iter__返回自身,__next__可以获取数据(终止是抛出StopIteration异常。可以被for循环。
生成器,在定义时是函数中重要包含yield就是生成器函数,执行函数获得生成器对象(一种特殊的迭代器);可以通过next取值 & 也可以通过for循环取值。
可迭代对象,含有 __iter__方法,且返回一个迭代器对象。可以被for循环。
"""

# 6. 看代码写结果
"""
666
1
18
99
1
999
999
1
99
"""

# 7. 看代码写结果,注意返回值。
"""
f3
f2
999
None
"""

# 8. 看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】
"""
class Foo(object):

def f1(self):
print('f1')

@staticmethod
def f2():
print('f2')

obj = Foo()
obj.f1() # f1
obj.f2() # f2

Foo.f1() # 报错
Foo.f2() # f2
"""

# 9.看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】
"""
f1
f2
f3
"""

# 10.看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】
"""
f1
f2
f3
"""

# 11.看代码写结果【如果有错误,则标注错误即可,并且假设程序报错可以继续执行】
"""
class Foo(object):
a1 = 1
__a2 = 2

def __init__(self, num):
self.num = num
self.__salary = 1000

def show_data(self):
print(self.num + self.a1)


obj = Foo(666)

print(obj.num) # 666
print(obj.a1) # 1
print(obj.__salary) # 报错
print(obj.__a2) # 报错
print(Foo.a1) # 1
print(Foo.__a2) # 报错
obj.show_data() # 667
"""

# 12.看代码写结果
"""
8
8 None
9
9 None
"""

# 13.看代码写结果
"""
1 1
666
666
"""

# 14.看代码写结果
"""
class Foo(object):
def __init__(self, num):
self.num = num


v1 = [Foo for i in range(10)]
v2 = [Foo(5) for i in range(10)]
v3 = [Foo(i) for i in range(10)]

print(v1) # [类,类,类...]
print(v2) # [对象(num=5),对象(num=5),对象(num=5)..]
print(v3) # [对象(num=0),对象(num=1),对象(num=2)..]
"""

# 15.看代码写结果
"""
1
2
3
"""

# 16.看代码写结果
"""
1 666
2 666
3 666
"""

# 17. 看代码写结果
"""
3
19 5
20 5
666 33
"""

# 18. 看代码写结果
"""
class StarkConfig(object):
def __init__(self, num):
self.num = num

def run(self):
self()

def __call__(self, *args, **kwargs):
print(self.num)


class RoleConfig(StarkConfig):
def __call__(self, *args, **kwargs):
print(345)

def __getitem__(self, item):
return self.num[item]


v1 = RoleConfig('alex')
v2 = StarkConfig("wupeiqi")

print(v1[1]) # l
print(v2[2]) # 报错
"""

# 19.补全代码
"""
class Context:
def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
pass

def do_something(self):
pass


with Context() as ctx:
ctx.do_something()
"""

# 20.看代码写结果
"""
我是武沛齐,年龄18,属于人事部
我是alex,年龄18,属于人事部
"""

# 21.分析代码关系,并写出正确的输出结果。
"""
中国
Node对象(title=河南省)
河南省
Node对象(title=河北省)
河北省
"""

# 22. 分析代码关系,并写出正确的输出结果。
"""
中国
河南省
河北省
石家庄
廊坊
雄安
"""

View Code

 

面试题

class Parent(object):
    x = 1
​
​
class Child1(Parent):
    pass
​
​
class Child2(Parent):
    pass
​
​
print(Parent.x, Child1.x, Child2.x) # 1 1 1
​
Child1.x = 2  # 在 Child类中新增实例变量x=2
print(Parent.x, Child1.x, Child2.x) # 1 2 1
​
Parent.x = 3
print(Parent.x, Child1.x, Child2.x) # 3 2 3

View Code

 

 

day19总结

  1. 了解 mro和c3算法

  2. python2和python3在面向对象中的区别。

  3. 内置函数

    staticmethod,classmethod,property,callable,type,isinstance,issubclass,super
    getattr,setattr,hasattr,delattr
  4. 异常处理

  5. 根据字符串的形式导入模块 import_module

  6. 根据字符串的形式操作成员 反射-getattr,setattr,hasattr,delattr

 作业

  1. super的作用?

  2. 看图分析类A的继承关系 

     

    看代码写结果
    
    class Foo(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        @property
        def message(self):
            return "{}-{}".format(self.name, self.age)
    
    
    class Bar(Foo):
        def __init__(self, email, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.email = email
    
        def total(self):
            data = "{}-{}-{}".format(self.name, self.age, self.email)
            return data
    
    
    obj1 = Foo("武沛齐", 20)
    print(obj1.message)
    
    obj2 = Bar("xx@live.com", "root", 100)
    print(obj2.message)
    obj2.total()
    看代码写结果
    
    class Foo(object):
        def __call__(self, *args, **kwargs):
            return 666
        
    data_list = [
        "武沛齐",
        dict,
        lambda :123,
        True,
        Foo,
        Foo()
    ]
    
    for item in data_list:
        if callable(item):
            val = item()
            print(val)
        else:
            print(item)
    如何主动触发一个异常?
    
    反射的作用?
    
    看代码写结果
    
    class Person(object):
        title = "北京"
    
        def __init__(self, name, wx):
            self.name = name
            self.wx = wx
    
        def show(self):
            message = "姓名{},微信:{}".format(self.name, self.wx)
            return message
    
        @property
        def message(self):
            return 666
    
        @staticmethod
        def something():
            return 999
    
    
    obj = Person("武沛齐", "wupeiqi666")
    
    print(getattr(obj, 'wx'))
    print(getattr(obj, 'message'))
    print(getattr(obj, 'show')()) 
    print(getattr(obj, 'something')())
     
    
    # 1.super的作用
    """
    根据类继承关系向上寻找成员
    """
    
    # 2. 类继承关系
    """
    A,B,C,M,D,F,J,G,H
    """
    
    # 3.看代码写结果
    """
    武沛齐-20
    root-100
    """
    
    # 4.看代码写结果
    """
    武沛齐
    {} 或 空字典
    123
    True
    Foo类的对象
    666
    """
    
    # 5.如何主动触发一个异常?
    """
    raise 异常类(...)
    """
    
    # 6.反射的作用?
    """
    以字符串的形式去对象中操作成员
    """
    
    # 7. 看代码写结果
    """
    wupeiqi666
    666
    姓名武沛齐,微信:wupeiqi666
    999
    """

    View Code

     

 

day20总结

  1. 了解常见设备和网络架构。

  2. 掌握常见网络词汇的意思。

  3. 了解B/S和C/S架构的区别。

  4. 基于Python的socket模块实现网络编程。

 

作业

  1. 简述 二层交换机 & 路由器 & 三层交换机 的作用。

  2. 简述常见词:IP、子网掩码、DHCP、公网IP、端口、域名的作用。

  3. 实现远程用户认证系统。

    客户端:
    1. 运行程序,连接服务端并获取服务端发送的欢迎使用xx系统信息。
    2. 输入用户名和密码,并将用户名和密码发送到服务端去校验。
    3. 登录失败,重试(Q退出)。
    4. 登录成功,进入系统,提示登录成功
    服务端:
    1. 客户端连接上服务端,返回 欢迎使用xx系统信息。
    2. 等待客户端发送用户名和密码进行校验(用户名和密码在文件中)
    3. 登录失败,返回错误信息。
    4. 登录成功,返回成功提示的内容。

client.py

import socket
import json

# 1. 向指定IP发送连接请求
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8001))

# 2.连接成功后,获取系统登录信息
message = client.recv(1024)
print(message.decode("utf-8"))

while True:
user = input("请输入用户名:")
pwd = input("请输入密码:")
content = "{}|{}".format(user, pwd)
client.sendall(content.encode("utf-8"))

reply = client.recv(1024)
info = json.loads(reply.decode("utf-8"))
if info['status']:
print(info['msg']) # 登录成功
break
else:
print(info['msg']) # 登录失败
# 关闭连接
client.close()

 

 sever.py

 

 

import socket
import json

# 1.监听本机的IP和端口
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 8001)) # 127.0.0.1 或 查看自己局域网本地IP地址
sock.listen(5)

while True:
# 2.等待,有人来连接(阻塞)
conn, addr = sock.accept()

# 3.连接成功后立即发送
conn.sendall("欢迎使用xx系统".encode("utf-8"))

while True:
# 3.等待接受信息
data = conn.recv(1024)
if not data:
break
data_string = data.decode("utf-8")
username, password = data_string.split('|')


file_object = open("db.csv", mode='r', encoding='utf-8')

is_success = False
for line in file_object:
user, pwd = line.strip().split(",")
if user == username and pwd == password:
is_success = True

file_object.close()

if is_success:
info = {"status": True, 'msg': "登录成功"}
conn.sendall(json.dumps(info).encode("utf-8"))
break
else:
info = {"status": False, 'msg': "登录失败"}
conn.sendall(json.dumps(info).encode("utf-8"))
# 5.关闭与此人的连接
conn.close()

# 6.停止服务端程序
sock.close()

View Code

 

 

day21总结

  1. OSI 7层模型

    应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
  2. UDP和TCP的区别

    UDP,速度快但无法保证数据的准确性。
    TCP,需要先创建可靠连接,在进行收发数据(ack)。
  3. TCP的三次握手和四次挥手

  4. 为什么会有粘包?如何解决?

  5. 如何让socket请求变成非阻塞?

  6. IO多路复用的作用?

    监测多个 IO对象 是否发生变化(可读/可写)。
    • IO多路复用 + 非阻塞 + socket服务端,可以让服务端同时处理多个客户端的请求。

    • IO多路复用 + 非阻塞 + socket客户端,可以向服务端同时发起多个请求。

作业(模块大作业)

请基于TCP协议实现一个网盘系统,包含客户端、服务端,各自需求如下:

  • 客户端

    • 用户注册,注册成功之后,在服务端的指定目录下为此用户创建一个文件夹,该文件夹下以后存储当前用户的数据(类似于网盘)。

    • 用户登录

    • 查看网盘目录下的所有文件(一级即可),ls命令

    • 上传文件,如果网盘已存在则重新上传(覆盖)。

    • 下载文件(进度条)

      先判断要下载本地路径中是否存在该文件。
      - 不存在,直接下载
      - 存在,则让用户选择是否续传(继续下载)。
      - 续传,在上次的基础上继续下载。
      - 不续传,从头开始下载。
  • 服务端

    • 支持注册,并为用户初始化相关目录。

      注册成功之后,将所有用户信息存储到特定的Excel文件中

       

       

    • 支持登录

    • 支持查看当前用户网盘目录下的所有文件。

    • 支持上传

    • 支持下载

 

 

day22总结

  1. 进程和线程的区别和应用场景。

  2. 什么是GIL锁

  3. 多线程和线程池的使用。

  4. 线程安全 & 线程锁 & 死锁

  5. 单例模式

 

作业

简述进程和线程的区别以及应用场景。

什么是GIL锁

手写单例模式

程序从flag a执行到falg b的时间大致是多少秒?

import threading
import time
def _wait():
    time.sleep(60)
# flag a
t = threading.Thread(target=_wait)
t.setDaemon(False)
t.start()
# flag b
程序从flag a执行到falg b的时间大致是多少秒?

import threading
import time
def _wait():
    time.sleep(60)
# flag a
t = threading.Thread(target=_wait)
t.setDaemon(True)
t.start()
# flag b
程序从flag a执行到falg b的时间大致是多少秒?

import threading
import time
def _wait():
    time.sleep(60)
# flag a
t = threading.Thread(target=_wait)
t.start()
t.join()
# flag b
读程序,请确认执行到最后number是否一定为0

import threading
loop = int(1E7)
def _add(loop = 1):
    global number
    for _ in range(loop):
        number += 1
def _sub(loop = 1):
    global number
    for _ in range(loop):
        number -= 1
number = 0
ta = threading.Thread(target=_add,args=(loop,))
ts = threading.Thread(target=_sub,args=(loop,))
ta.start()
ta.join()
ts.start()
ts.join()
读程序,请确认执行到最后number是否一定为0

import threading
loop = int(1E7)
number = 0

def _add(loop = 1):
    global number
    for _ in range(loop):
        number += 1
def _sub(loop = 1):
    global number
    for _ in range(loop):
        number -= 1

ta = threading.Thread(target=_add,args=(loop,))
ts = threading.Thread(target=_sub,args=(loop,))
ta.start()
ts.start()
ta.join()
ts.join()
data.txt 文件中共有 10000 条数据,请为每 100行 数据创建一个线程,并在线程中把当前100条数据的num列相加并打印。

subscription_id,erotic,num
ASDFOKASDJF423KASDFJASDF,5,1
FSD23R23SFSDF4DFGDFGDFGDF,5,99
ASDDSFGWERTCERT44GFGDSFG,5,2
FFFFFFSDSVFG5RTFGDDFFFFA,5,11
ASDFASDF3234XCVWEGDFGSAF,5,1
...
 

 

# 1.简述进程和线程的区别以及应用场景。
"""
线程,是计算机中可以被cpu调度的最小单元(真正在工作)。
进程,是计算机资源分配的最小单元(进程为线程提供资源)。
一个进程中可以有多个线程,同一个进程中的线程可以共享此进程中的资源。
由于GIL锁的存在,控制一个进程中同一时刻只有一个线程可以被CPU调度。所以
- 计算密集型,适合用多进程开发。
- IO密集型,适合用多线程开发。
"""

# 2.什么是GIL锁
"""
GIL是Cpython解释器特有的一个全局解释器锁,控制一个进程中同一时刻只有一个线程可以被CPU调度。
同时像列表、字典等常见对象的线程数据安全,也得益于GIL。
"""

# 3.单例模式
"""
import threading

class Singleton:
instance = None
lock = threading.RLock()

def __new__(cls, *args, **kwargs):

if cls.instance:
return cls.instance
with cls.lock:
if cls.instance:
return cls.instance
time.sleep(0.1)
cls.instance = object.__new__(cls)
return cls.instance
"""

# 4.程序从flag a执行到falg b的时间大致是多少秒?
"""
60
"""

# 5.程序从flag a执行到falg b的时间大致是多少秒?
"""
0
"""

# 6.程序从flag a执行到falg b的时间大致是多少秒?
"""
60
"""

# 7.读程序,请确认执行到最后number是否一定为0
"""
结果为0
"""

# 8.读程序,请确认执行到最后number是否一定为0
"""
结果不一定为0
"""

# 9.data.txt 文件中共有 10000 条数据,请为每 100行 数据创建一个线程,并在线程中把当前100条数据的num列相加并打印。
"""
import threading


def task(row_list):
num_list = [int(row.split(",")[-1]) for row in row_list]
result = sum(num_list)
print(result)


def run():
file_object = open('data.txt', mode='r', encoding='utf-8')
file_object.readline()
row_list = []
for line in file_object:
row_list.append(line.strip())
if len(row_list) == 100:
t = threading.Thread(target=task, args=(row_list,))
t.start()
row_list = [] # 千万不要用 row_list.clear()
if row_list:
t = threading.Thread(target=task, args=(row_list,))
t.start()

file_object.close()


if __name__ == '__main__':
run()

"""

View Code

 

day23总结

  1. 了解的进程的几种模式

  2. 掌握进程和进程池的常见操作(以后公司写一些脚本 爬虫会用到进程池 , 项目中框架里会有现成的)

  3. 进程之间数据共享

  4. 进程锁

  5. 协程、进程、线程的区别(概念)

复制代码
请定义一个函数,用于计算一个字符串中字符a出现的次数并通过return返回。

参数,字符串。

返回值,字符串中 a 出现的次数。

 第一题
"""
def char_count(text):
    count = 0
    for char in text:
        if char == 'a':
            count += 1
    return count


result = char_count("89alskdjf;auqkaaafasdfiojqln")
"""
写函数,判断用户传入的一个值(字符串或列表或元组任意)长度是否大于5,并返回真假。


# 第二题
"""
def judge_length(data):
    if len(data) > 5:
        return True
    return False


result = judge_length("武沛齐武沛齐")
print(result)
"""
写函数,接收两个数字参数,返回比较大的那个数字(等于时返回两个中的任意一个都可以)。

# 第三题
"""
def get_bigger(num1, num2):
    if num1 > num2:
        return num1
    return num2


result = get_bigger(11, 22)
"""
写函数,函数接收四个参数分别是:姓名,性别,年龄,学历,然后将这四个值通过"*"拼接起来并追加到一个student_msg.txt文件中。

 第四题
"""
def write_file(name, gender, age, degree):
    data_list = [name, gender, age, degree]
    data = "*".join(data_list)
    with open('student_msg.txt', mode='a', encoding='utf-8') as file_object:
        file_object.write(data)


write_file("武沛齐", "男", "18", "博士")
"""
补充代码,实现如下功能:

【位置1】读取文件中的每一行数据,将包含特定关键的数据筛选出来,并以列表的形式返回。

【位置1】文件不存在,则返回None

【位置2】文件不存在,输出 "文件不存在",否则循环输出匹配成功的每一行数据。

def select_content(file_path,key):
    # 补充代码【位置1】

result = select_content("files/xxx.txt","股票")
# 补充代码【位置2】
 第五题
"""
import os


def select_content(file_path, key):
    # 补充代码【位置1】
    if not os.path.exists(file_path):
        return
    data_list = []
    with open(file_path, mode='r', encoding='utf-8') as file_object:
        for line in file_object:
            if key in line:
                data_list.append(line)
    return data_list


result = select_content("files/xxx.txt", "股票")
if result == None:
    print("文件不存在")
else:
    print(result)
"""
补充代码,实现敏感词替换的功能。

def change_string(origin):
    # 补充代码,将字符串origin中中的敏感词替换为 **,最后将替换好的值返回。 
    data_list = ["苍老师","波多老师","大桥"]
    
text = input("请输入内容:")
result = change_string(text)
print(result)
 第六题
"""
def change_string(origin):
    # 补充代码,将字符串origin中中的敏感词替换为 **,最后将替换好的值返回。
    data_list = ["苍老师", "波多老师", "大桥"]
    for item in data_list:
        origin = origin.replace(item, "**")
    return origin


text = input("请输入内容:")
result = change_string(text)
print(result)
"""
基于函数实现用户认证,要求:

写函数,读取的用户信息并构造为字典(用户信息存放在files/user.xlsx文件中)



 

 

# 构造的字典格式如下
user_dict = {
    "用户名":"密码"
    ...
}
用户输入用户名和密码,进行校验。(且密码都是密文,所以,需要将用户输入的密码进行加密,然后再与Excel中的密文密码进行比较)

import hashlib

def encrypt(origin):
    origin_bytes = origin.encode('utf-8')
    md5_object = hashlib.md5()
    md5_object.update(origin_bytes)
    return md5_object.hexdigest()


p1 = encrypt('admin')
print(p1) # "21232f297a57a5a743894a0e4a801fc3"

p2 = encrypt('123123')
print(p2) # "4297f44b13955235245b2497399d7a93"

p3 = encrypt('123456')
print(p3) # "e10adc3949ba59abbe56e057f20f883e"
扩展:密码都不是明文。

注册京东,京东存储:用户名和密码(密文)

登录京东:用户名& 密码。

 

# 第七题
"""
import hashlib
from openpyxl import load_workbook


def get_user_dict():
    user_dict = {}
    wb = load_workbook("files/user.xlsx")
    sheet = wb.worksheets[0]
    for row in sheet.rows:
        user_dict[row[1].value] = row[2].value
    return user_dict


def encrypt(origin):
    origin_bytes = origin.encode('utf-8')
    md5_object = hashlib.md5()
    md5_object.update(origin_bytes)
    return md5_object.hexdigest()


user = input("请输入用户名:")
pwd = input("请输入密码:")

encrypt_password = encrypt(pwd)

user_dict = get_user_dict()

db_password = user_dict.get(user)

if encrypt_password == db_password:
    print("登录成功")
else:
    print("登录失败")
"""
 

 
复制代码
版权声明:本文为贰号猿原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/erhuoyuan/p/16982962.html