一、集合
与列表和元组不同,集合是无序的,也无法通过数字进行索引。此外,集合中的元素不能重复 创建集合: 使用set函数 集合操作: s = set([3,5,9,10]) #创建一个数值集合 t = set("Hello") #创建一个唯一字符的集合 a = t | s # t 和 s的并集 b = t & s # t 和 s的交集 c = t – s # 求差集(项在t中,但不在s中) d = t ^ s # 对称差集(项在t或s中,但不会同时出现在二者中) t.add(‘x‘) # 添加一项 s.update([10,37,42]) # 在s中添加多项 t.remove(‘H‘) #删除一项 len(s) set 的长度 x in s 测试 x 是否是 s 的成员 x not in s 测试 x 是否不是 s 的成员 s.issubset(t) s <= t 测试是否 s 中的每一个元素都在 t 中 s.issuperset(t) s >= t 测试是否 t 中的每一个元素都在 s 中 s.union(t) s | t 返回一个新的 set 包含 s 和 t 中的每一个元素 s.intersection(t) s & t 返回一个新的 set 包含 s 和 t 中的公共元素 s.difference(t) s - t 返回一个新的 set 包含 s 中有但是 t 中没有的元素 s.symmetric_difference(t) s ^ t 返回一个新的 set 包含 s 和 t 中不重复的元素 s.copy() 返回 set “s”的一个浅复制 s.update(t) s |= t 返回增加了 set “t”中元素后的 set “s” s.intersection_update(t) s &= t 返回只保留含有 set “t”中元素的 set “s” s.difference_update(t) s -= t 返回删除了 set “t”中含有的元素后的 set “s” s.symmetric_difference_update(t) s ^= t 返回含有 set “t”或者 set “s”中有而不是两者都有的元素的 set “s” s.add(x) 向 set “s”中增加元素 x s.remove(x) 从 set “s”中删除元素 x, 如果不存在则引发 KeyError s.discard(x) 如果在 set “s”中存在元素 x, 则删除 s.pop() 删除并且返回 set “s”中的一个不确定的元素, 如果为空则引发 KeyError s.clear() 删除 set “s”中的所有元素
二、函数
创建函数: def关键字 注意:return,在函数中,一旦执行return,函数执行过程立即终止 第一种:位置或关键字参数 这种参数是Python中默认的参数类型,定义这种参数后,可以通过位置参数,或者关键字参数的形式传递参数: eg: ## 位置或者关键字参数 ## 这个是Python的默认参数类型 ## 示例:arg2提供了默认value def func(arg1, arg2="World!"): print arg1, arg2 ## func可以通过位置参数形式调用 func("Hello", "MitchellChu") ## 也可以通过关键字参数的形式来调用func func(arg1="Hello", arg2="World!") ## 当然,混合的方式也是完全没有问题的 func("Hello", arg2="World!") 第二种方式:仅适用位置参数的形式 这种形式在需要将参数传递给函数(方法)时,仅能通过位置参数的传递方式。这种形式对于Python的开发者来说,暂时并没有办法使用。这种形式现在仅存在Python的很多内建的函数上: eg: ## Positional-only parameter has no syntax to define ## 虽然无定义方法,但内建的很多函数都是仅接受位置参数的 abs(-3) ## correct abs(a=3) ## wrong ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: abs() takes no keyword arguments pow(x=2,y=3) ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: pow() takes no keyword arguments pow(2,3) ## 8 第三种:任意数量的位置参数(带单个星号参数) 任意数量的位置参数在定义的时候是需要一个星号前缀来表示,在传递参数的时候,可以在原有参数的后面添加任意多个参数,这些参数将会被放在元组内提供给函数(方法): eg: ## var-positional parameter ## 定义的时候,我们需要添加单个星号作为前缀 def func(arg1, arg2, *args): print arg1, arg2, args ## 调用的时候,前面两个必须在前面 ## 前两个参数是位置或关键字参数的形式 ## 所以你可以使用这种参数的任一合法的传递方法 func("hello", "Tuple, values is:", 2, 3, 3, 4) ## Output: ## hello Tuple, values is: (2, 3, 3, 4) ## 多余的参数将自动被放入元组中提供给函数使用 ## 如果你需要传递元组给函数 ## 你需要在传递的过程中添加*号 ## 请看下面例子中的输出差异: func("hello", "Tuple, values is:", (2, 3, 3, 4)) ## Output: ## hello Tuple, values is: ((2, 3, 3, 4),) func("hello", "Tuple, values is:", *(2, 3, 3, 4)) ## Output: ## hello Tuple, values is: (2, 3, 3, 4) 第四种:任意数量的关键字参数(带两个星号参数) 任意数量的关键字参数在定义的时候,参数名称前面需要有两个星号(**)作为前缀,这样定义出来的参数,在传递参数的时候,可以在原有的参数后面添加任意多个关键字参数,关键字参数是使用[参数名称=参数值]的形式进行传递: eg: ## var-keywords parameter ## 定义的时候,需要两个星号作为前缀 def func(arg1, arg2, **kwargs): print arg1, arg2, kwargs func("hello", "Dict, values is:", x=2, y=3, z=3) ## Output: ## 多余的参数将自动被放入字典中提供给函数使用 ## 如果你需要直接传递字典给函数 ## 你需要在传递的过程中添加** ## 此时如果还有关键字参数应在字典前提供完成 ## 不能在字典后再提供 ## 请看下面例子中的输出差异: func("hello", "Dict., values is:", **{‘x‘:2, ‘y‘:3, ‘z‘:3}) ## hello Dict., values is: {‘y‘: 3, ‘x‘: 2, ‘z‘: 3} func("hello", "Dict., values is:", **{‘x‘:2, ‘y‘:3, ‘z‘:3,}) ## hello Dict., values is: {‘y‘: 3, ‘x‘: 2, ‘z‘: 3} func("hello", "Dict., values is:", {‘x‘:2, ‘y‘:3, ‘z‘:3}) ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: func() takes exactly 2 arguments (3 given) func("hello", "Dict., values is:", s=3, **{‘x‘:2, ‘y‘:3, ‘z‘:3,}) ## hello Dict., values is: {‘y‘: 3, ‘x‘: 2, ‘s‘: 3, ‘z‘: 3} ## 提供了重复的参数 func("hello", "Dict., values is:", y=3, **{‘x‘:2, ‘y‘:3, ‘z‘:3,}) ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: func() got multiple values for keyword argument ‘y‘ 总结:四种参数形式中仅有第二种Python没有提供定义的方法,其他三种在定义的时候也需要注意,定义的时候应该根据Python的解析规律进行定义,其中: 位置或关键字参数应该在最前面,其中,没有默认值的应该在有默认值的参数前面 任意数量位置参数应该放在所有位置或关键字参数的后面 任意数量关键字参数应该放在任意数量位置参数的后面 注意:任意数量位置参数和任意数量关键字参数只能在定义中定义一次。
三、三元运算及lamdba表达式
三元运算: >>> 1 if True else 0 1 >>> 1 if False else 0 0 >>> "Fire" if True else "Water" ‘Fire‘ >>> "Fire" if False else "Water" ‘Water‘ lamdba表达式: lambda只是一个表达式,函数体比def简单很多。 lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。 lambda表达式是起到一个函数速写的作用。允许在代码内嵌入一个函数的定义。 f = lambda x,y,:x+y f(2,3) 5
四、Python中的一些内置函数
abs() 取得绝对值 all() 所有为真,才为真 any() 只要有一个真,就为真 ascii() 自动执行对象的__repr__方法 bin() 将10进制转换为2进制 oct() 将10进制转换为8进制 hex() 将10进制转换为16进制 bool() 判断值是True还是False bytes() 字符串转换字符类型
五、作业
#_*_coding:utf-8_*_ import json,collections LINE_LIST = [] #配置文件中的每一行将作为一个元素,保存在该列表中 FILE_DICT = collections.OrderedDict() #下方代码会将每个模块的头部与内容作为一个键值对添加到该有序字典中,以下称配置文件字典 file = open(‘ConfigFile‘,‘r‘) for line in file.readlines(): LINE_LIST.append(line) #将每一行作为一个元素向line_list中追加,以下称line_list列表为配置文件列表 file.close() for file_line in LINE_LIST: #循环配置文件列表的每一行 #以模块头部分类,头部作为键,值暂时设置为空列表,之后会将该模块的内容每一行作为一个元素添加到列表中 if file_line[0:6] == ‘global‘ or file_line[0:8] == ‘defaults‘ or file_line[0:6] == ‘listen‘ or file_line[0:8] == ‘frontend‘ or file_line[0:7] == ‘backend‘: file_row = file_line #用另一个变量记录下模块头部,方便下方添加值时,系统知道是为哪个模块添加 FILE_DICT[file_line] = [] elif file_line[0] == ‘ ‘ or file_line == ‘\n‘: #如果该行的第一个字符为空,或者该行为‘\n‘,说明该行为模块的值 FILE_DICT[file_row].append(file_line) #那么将该行加入到相应的模块列表中 def write_in_file(): """ 该函数用来将改变后的配置更新到配置文件中 :return: """ new_line_list = [] #该列表用来将改变后的配置文件字典中的键值对作为一个元素添加到列表中 for k,v in FILE_DICT.items(): #因为在配置文件字典中,值为一个列表,所以这里将值用join方法连起来 new_line_list.append(‘%s%s‘ % (k, "".join(v))) #将配置文件字典中的键值对作为一个元素添加到列表中 with open(‘ConfigFile‘,‘w‘) as write_file: #打开配置文件,将更新后的内容写到配置文件中 for i in new_line_list: write_file.writelines(i) def query_backend(): """ 该函数用来获取haproxy配置文件中对应backend记录的值 :return: 如果backend不存在,返回"该backend不存在",否则返回该backend记录的值 """ input_line = input("请输入backend:") #让用户输入backend 如:www.oldboy.com #display_backend变量的格式将为 ‘backend www.oldboy.com\n‘ 因为文件中就为该格式 input_backend = ‘backend ‘ + input_line + ‘\n‘ if input_backend in FILE_DICT.keys(): # #如果配置文件字典中存在用户输入的backend头部 display_list = FILE_DICT[input_backend] #将backend对应的值(一个列表)赋到一个变量上 for i in display_list: return(i) #输出每个元素 else: #如果配置文件字典中不存在用户输入的backend头部 return("不存在该backend记录") def add_backend(): """ 该函数用来增加haproxy配置文件中对应backend记录的值,或者新建一个backend记录,并将对应值写到配置文件中 :return: """ add_backend = input("请输入要新加的backend记录:") #因为这个会用到json将用户输入的字符串格式转化要求的字典格式,会引发很多错误,所以这里用异常处理来避免因格式引起的错误 try: #用户输入格式必须为{"backend": "test.oldboy.org","record":{"server": "100.1.7.9","weight": 20,"maxconn": 30}} add_backend = json.loads(add_backend) #用户输入的为字符串格式,通过json转化为字典格式 #backend_title变量的格式将为 ‘backend www.oldboy.com\n‘ 因为文件中就为该格式 backend_title = "backend {0}\n".format(add_backend[‘backend‘]) #content的格式为‘ server 100.1.7.9 100.1.7.9 weight 20 maxconn 30\n‘,文件中就为次格式 content = " server {0} {0} weight {1} maxconn {2}\n".format(add_backend["record"]["server"], add_backend["record"]["weight"], add_backend["record"]["maxconn"]) except Exception as e: return("error") if backend_title in FILE_DICT.keys(): #如果配置文件字典中已存在用户输入的backend头部 if content in FILE_DICT[backend_title]: #并且值也存在 return("已存在") else: #如果值不存在 FILE_DICT[backend_title].append(content) #将值添加到配置文件字典中backend模块的值里(backend的值为一个列表) write_in_file() #调用函数将最新内容写入磁盘 return ("添加完成") else: #如果配置文件字典中不存用户输入的backend头部 FILE_DICT[backend_title] = [content] #创建一个键值对,键为用户输入的backend头部,值为用户输入的backend值 write_in_file() #调用函数将最新内容写入磁盘 return ("添加完成") def del_backend(): """ 该函数用来删除用户输入的在haproxy配置文件中的backend记录中的值 :return: """ del_backend = input("请输入要删除的backend记录:") #因为这个会用到json将用户输入的字符串格式转化要求的字典格式,会引发很多错误,所以这里用异常处理来避免因格式引起的错误 try: #用户输入格式必须为{"backend": "test.oldboy.org","record":{"server": "100.1.7.9","weight": 20,"maxconn": 30}} del_backend = json.loads(del_backend) #用户输入的为字符串格式,通过json转化为字典格式 #backend_title变量的格式将为 ‘backend www.oldboy.com\n‘ 因为文件中就为该格式 backend_title = "backend {0}\n".format(del_backend[‘backend‘]) #content的格式为‘ server 100.1.7.9 100.1.7.9 weight 20 maxconn 30\n‘,文件中就为次格式 content = " server {0} {0} weight {1} maxconn {2}\n".format(del_backend["record"]["server"], del_backend["record"]["weight"], del_backend["record"]["maxconn"]) except Exception as e: return("error") if backend_title in FILE_DICT.keys(): #如果配置文件字典中存在用户输入的backend头部 if content in FILE_DICT[backend_title]: #并且值也存在 FILE_DICT[backend_title].remove(content) #在backend对应的列表中将该值删除 if FILE_DICT[backend_title] == []: #如果用户输入的backend头部对应的值为空,删除该backend记录 del FILE_DICT[backend_title] write_in_file() #调用函数将最新内容写入磁盘 return "已删除(该backend记录中无任何值,已将该backend记录删除)" else: write_in_file() #调用函数将最新内容写入磁盘 return("已删除") else: #如果值不存在 return("该backend记录中不存在该值") else: #如果配置文件字典中不存在用户输入的backend头部 return("不存在该backend记录") while True: USER_CHOICE = input("1、获取ha记录\n2、增加ha记录\n3、删除ha记录\n请输入你的选择(输入‘q‘退出):") if USER_CHOICE.strip().isdigit(): #判断用户输入是否为数字 if USER_CHOICE == ‘1‘: #如果用户输入1,调用query_backend()函数 value = query_backend() print(value) break if USER_CHOICE == ‘2‘: #如果用户输入2,调用add_backend()函数 value = add_backend() if value == "error": print("你的输入数据格式有误,请重新输入") continue else: print(value) break if USER_CHOICE == ‘3‘: #如果用户输入3,调用user_choice()函数 value = del_backend() if value == "error": print("你的输入数据格式有误,请重新输入") continue else: print(value) break else: print("你的输入有误,请重新输入") elif USER_CHOICE == ‘q‘: #如果用户输入q,结束循环 break else: print("你的输入有误,请重新输入") 配置文件: global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 info defaults log global mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms option dontlognull listen stats :8888 stats enable stats uri /admin stats auth admin:1234 frontend oldboy.org bind 0.0.0.0:80 option httplog option httpclose option forwardfor log global acl www hdr_reg(host) -i www.oldboy.org use_backend www.oldboy.org if www backend www.oldboy.org server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000 backend buy.oldboy.org server 100.1.7.90 100.1.7.90 weight 20 maxconn 3000
六、作业流程图
时间: 2024-10-23 15:23:30