set集合

集合是一个无序的、不可重复的集合。主要作用有:

1.去重,把一个列表变成集合,就等于去重了。
2.关系测试,测试两组数据之前的交集、差集、并集等关系

常用操作

创建、交集、并集、差集、对称差集、子集、父集 长度、判断元素是否在集合中、删除

 

# 创建集合:
set1 = set([1,2,3,4,5,90])
set2 = set([2,378,98])

# 交集 (在set1和set2中都有的元素)
print(set1.intersection(set2))
print(set1&set2)

# 并 set1和set2的所有元素的集合
print(set1.union(set2))
print(set1|set2)
# 差集 :在set1中不在set2中
print(set1.disfference(set2))
print(set1-set2)
# 对称差集 项在t或s中,但不会同时出现在二者中
print(set1^set2)
print(set1.symmetric_difference(set2))
# 子集
print(set1.issubset(set2))
# 父集
print(set1.issuperset(set2))
# 在set中添加一项
print(set1.add(45))
# 在set 中添加多项
print(set1.update(set2))
# remove删除指定项,若不存在,会报错
print(set1.remove(2))
print(set1.discard(2))  # remove删除指定项,如不存在,不报错
print(set1.pop())  # 删除任意一项
set1.discard(98)

# 集合的长度
print(len(set1))
x = ''
if x in set1:# 判断 x是否在set1 中。
    pass
if x not in set1:# 判断集合不在set1中。
    pass
if set1.issubset(set2): # s <= t 测试是否s中的每一个元素都在t中
    pass

文件操作

对文件的操作流程:

1.打开文件,得到文件句柄并赋值给一个变量
2.通过句柄对文件进行操作
3.关闭文件

基本操作:

f = open("yesterday",'r',encoding='utf-8')  # 只可读
f2 =open("yesterday2",'w',encoding="utf-8")  # 可写,覆盖原来的内容
f3=open("yesterday2",'a',encoding="utf-8")  # 追加不可读
data = f.read() # 打印所有内容
f2.write("我爱北京天安门\n")
f2.write("天安门\n")

f4 = open("yesterday","a+",encoding='utf-8')  # 新建文件
print(f4.readline())  #
print(f4.readline())  # 读一行
print(f4.encoding) # 打印文件句柄的编号方式
print(f4.tell())  # 显示当前文件句柄的位置
print(f4.seek(10))  # 件句柄调到第10个位置,
# 备注:在写文件时,如果使用r+ ,w+,时,不使用seek时,在文件末尾追加写入的内容
#  若使用,seek(),就覆盖写入了,不在使用追加模式
f4.truncate(10) # 从文件开头到10 截断

f4.flush()  # 将数据由内存刷入到文件或者硬盘
print(f4.readline())
for line in f4:
    print(line)  # 只在内存中保存一行

f5 = open("test.txt",'rb')
print(f5.readline())
f5.close()

打开文件的模式有:

r,只读模式(默认)。
w,只写模式。【不可读;不存在则创建;存在则删除内容;】
a,追加模式。【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件

r+,可读写文件。【可读;可写;可追加】
w+,写读
a+,同a

with语句:

python 2.7中
with open('log','r') as f:
 for line in f:
     print(line)

python3中:
with open('log1') as obj1, open('log2') as obj2:
       pass

编码方式

在python2中,默认编码是ASSIC编码,若在文件中指定文件的编码方式为“utf-8",若想转化成gbk,需要先解码为unicode,转编码为gbk

例如:

#!/usr/bin/env python
#-*- coding:utf-8 -*-
#author luotianshuai

import chardet
tim = '你好'
print chardet.detect(tim)
#先解码为Unicode编码,然后在从Unicode编码为GBK
new_tim = tim.decode('UTF-8').encode('GBK')
print chardet.detect(new_tim)

#结果
'''
{'confidence': 0.75249999999999995, 'encoding': 'utf-8'}
{'confidence': 0.35982121203616341, 'encoding': 'TIS-620'}

  python3中:

在python3中,默认的就是unicode

# author:snate
tim =u"你好"
new_tim = tim.encode('GBK')直接编码就可以。
print(new_tim)
new_time=tim.encode("GBK").decode("GBK").encode("GB2312")
print(new_tim)

面向对象、面向过程、函数式编程

面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。
它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用

函数的基本语法及特征

定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
函数的特征:
减少重复代码
使程序变的可扩展
使程序变得易维护

函数的定义:

语法:

def function():
     print("in the function")

还可以传递参数:

def Sum(x,y):
     sum = x +y 
     return sum

形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。

 位置参数和关键字参数、默认参数、可变参数

#!/usr/bin/env python 
# _*_ encoding:utf-8 _*_
# author:snate
# 位置参数和关键字参数
def test(x,y,z):
    print(x,y,z)
# 默认参数
def test2(sex,name="alex",age=12):
    print(sex,name,age)
# 参数个数不固定的形式参数
def test3(name,*args):
    print(name,args)
def test4(name,**kwargs):
    print(name,kwargs)
test(1,2,3) # 位置参数:实参和形参必须一一对应
test(x=1,y=2,z=2)
test(x=1,z=2,y=2) # 关键字参数与位置无关,不必一一对应
test2("女",age=25,name=12)  # 默认参数必须放到后面,
test3("gxw",1,1,23,4,["nihao",2,3,5]) #*args 会把多传入的多个参数变成一个元组形式
test3("gxw",*[1,2,3,4,5]) # *args 会把多传入的参数变成一个元组形式
test4(name="alex",age=12,sex="f",id=1)  # *kwargs 会把多传入的关键字参数变成一个dict形式
'''
1 2 3
1 2 2
1 2 2
女 12 25
gxw (1, 1, 23, 4, ['nihao', 2, 3, 5])
gxw (1, 2, 3, 4, 5)
alex {'id': 1, 'sex': 'f', 'age': 12}
'''

return

在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用

#!/usr/bin/env python 
# _*_ encoding:utf-8 _*_
# author:snate
school = "oldboy Edu."
name = "alec"
def test1(name):
    print("修改前:"+name)
    name = "alex"
    print("修改后:"+name)
    global school
    school = "MaGe"
    print(school)

test1(name)
print(school)

备注:为了在函数中修改全局变量的值,需要global声明,但是在以后的工作中禁用。

递归

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数

def calc(n):
    print(n)
    if int(n/2) ==0:
        return n
    return calc(int(n/2))
calc(10)
'''
10
5
2
1
'''

 递归的特征:

递归特征:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

高阶函数

变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

def add(x,y,f):
    return f(x) + f(y)

res = add(3,-6,abs)
print(res)

 作业1:用python实现简答的sed替换功能

 ReadMe:

这个一个使用python实现简单sed功能的程序 
 个人介绍 
  name:Gaoxuewu 
 nickName:snate 
 blog_addr: http://www.cnblogs.com/itlinux/p/5749369.html 
 
 项目需求 
 利用python实现shell中的sed的简单替换功能 
 功能介绍 
  将文件打开,一行一行的读,判断每行中,是否存在要替换的字符,若存在就替换 将替换后的行写入到新的文件;若不存在直接将读出的行写入到另一个文件。 
 
 环境依赖 
  python3.* 
 window/linux os 
 os模块 
 sys模块 
 
 目录结构 
 testSed
├── __init__.py
├── README.md # 程序介绍
├── testSed FlowChart # 程序流程图
├──yesterday # 需要读取的文件
├── yesterday.bak  #替换之前,文件的备份
 
 运行说明 
 在搭建好的python环境中,运行python testshell.py "年少轻狂" "Alex 很狂",就能实现用"Alex 很狂"替换"年少轻狂"的功能。 

流程图:

程序:

#!/usr/bin/env python 
# _*_ encoding:utf-8 _*_
# author:snate
'''
将yesterday文件中的“年少轻狂”替换成“alex 很狂"
'''
from sys import argv
import os
f1 = open("yesterday", "r", encoding="utf-8")
f2 = open("yesterday.bak", "w", encoding="utf-8")
for line in f1:
    if argv[1] in line: #"年少轻狂"
        line = line.replace(argv[1], argv[2]) # "---》alex 很狂"
    f2.write(line)
f1.close()
f2.close()
os.rename("yesterday","yesterday-bak")
os.rename("yesterday.bak","yesterday")

作业2:查找、修改、增加和删除proxy的内容

 Readme:

# 这个一个关于proxy配置文件增、删、查的程序

### 个人介绍
* name:Gaoxuewu
* nickName:snate
* email:hangtiangazi@163.com
* blog_addr:http://www.cnblogs.com/itlinux/p/5749369.html

### 功能介绍
* 查询时,输入域名,显示域名的相关的backend的信息
* 删除时,输入域名,能够删除域名以及配置服务器相关的信息
* 增加时,需要输入配置信息的字典,字典中包含backend的域名信息,以及包含IP,Maxconn,server的record列表
     1.例如:输入内容为:修改需输入内容举例:{"backend": "test.oldboy.org","record":{"server": "100.1.7.9","weight": 20,"maxconn": 30}}
     程序会自动判断输入的格式是否正确,若不正确,提示用户重新输入,直到输入正确的格式。 
     2.根据输入的内容的backend的域名,判断域名是否不在,不存在,添加域名,和需要配置的服务器信息;
     3.若域名存在,判断域名的服务器信息是否存在,若不在提供用户信息已存在,不需要修改文件;若不存在,
       在域名信息后面增加该信息。
       
### 环境依赖:
* python3以上版本
* linux/windows os 
* sys 模块
* os 模块
* time模块 

###目录结构:
    testProxy
    ├── __init__.py
    ├── README.md # 程序介绍
    ├── testProxy FlowChart # 程序流程图
    ├──proxy # proxy 配置文件
    ├── proxy.bak_.... proxy的备份文件
    ├── proxy.log # 日志文件
    ├── tetsProxy.py # 程序
       ├──search_backend(search_domain_name) # 查找域名信息
       ├──input_format(add_domain_info_str) # 判断输入域名及服务器的配置信息是否正确
       ├──add_backend() # 添加域名信息
       ├──dek_backend(del_domain_name) # 删除域名相关信息
       ├──main() #主程序
  
### 运行说明
在搭建好的python环境中,运行python testProxy.py 即可。

  程序流程图:

程序:

#!/usr/bin/env python
# _*_ encoding:utf-8 _*_
# author:snate
# 通过域名查询proxy的函数
import json
import time
import os
time_fort1 = "%Y-%m-%d %H:%M:%S"
time_fort2 = "%Y-%m-%d-%H-%M-%S"
current_time = time.strftime(time_fort1)
bak_time = time.strftime(time_fort2)
# 查找函数,根据输入的域名,返回域名的详细信息
def search_backend(search_domain_name):
    '''
    :param : Domain name
    :return: the specific information of Daomain ,Fomat:list
    '''
    f = open("proxy",'r',encoding="utf-8")
    info_list=[]
    Flag = 0 # 设置标志位 默认值为0 表示为匹配
    for line in f:
        line = line.strip() # 去掉两端的空格和换行
        if line == "backend %s" % search_domain_name:
            Flag = 1 # 若匹配上默认值为1
        elif line.startswith("backend"):
            Flag = 0
        elif Flag == 1 and  len(line) != 0: # 接着循环,将doamain的信息保存到info_list中。
            info_list.append(line)
    f.close()
    return info_list
# 判断输入的的域名信息及服务器的配置信息是否正确
def input_format(add_domain_info_str):
    '''
    :param add_domain_info_str:
    :return: boolean
    '''
    add_domain_content = json.loads(add_domain_info_str)
    try:
        add_domain_name = add_domain_content["backend"]
        add_domain_server = add_domain_content["record"]["server"]
        add_domain_weight = add_domain_content["record"]["weight"]
        add_domain_maxconn = add_domain_content["record"]["maxconn"]
    except:
        return False
    else:
        return True
# 添加域名信息
def add_backend():
    '''
    :return: None
    '''
    while True:
        add_domain_info_str = input("请输入用户要增加的配置信息:")
        Fort_Flag = input_format(add_domain_info_str)
        if Fort_Flag :
            add_domain_content = json.loads(add_domain_info_str)
            add_domain_name = add_domain_content["backend"]
            add_domain_server = add_domain_content["record"]["server"]
            add_domain_weight = add_domain_content["record"]["weight"]
            add_domain_maxconn = add_domain_content["record"]["maxconn"]
            add_domain_server_info = "server %s %s weight %s maxconn %s "%(add_domain_server,add_domain_server,\
                                    add_domain_weight,add_domain_maxconn)
            info_list = search_backend(add_domain_name)
            if len(info_list) == 0:
                with open("proxy","r",encoding="utf-8") as proxy_read, \
                        open("new_proxy","w",encoding="utf-8") as proxy_bak_write:
                    content_list = proxy_read.readlines()
                    content_list.append("\n")
                    content_list.append("backend %s\n" %add_domain_name)
                    content_list.append("%s %s" % (8*" ", add_domain_server_info))
                    proxy_bak_write.writelines(content_list)
                # 提示用户没有域名信息,将配置信息添加到配置文件最后
                print("No domain name,We will add to the end of the proxy!")
                time.sleep(1)
                print('''\033[31;1mInformation has been added successly!!!!\033[0m''')
                os.rename("proxy","proxy.bak_%s" % bak_time)
                os.rename("new_proxy", "proxy")
                with open("proxy.log", 'a+',encoding='utf-8') as log_write:
                    log_write.write("%s ad d the %s into proxy config successfully!\n" %(current_time,add_domain_server_info))
            else:
                if add_domain_server_info in info_list: # 若服务器信息重叠,提示用户信息重叠,不需要配置文件
                    print("\033[31;1mServer_info:%s is existed!,don't need add!!!!\033[0m" % add_domain_server_info)
                else:
                    info_list.append(add_domain_server_info)
                    with open("proxy", 'r', encoding='utf-8') as proxy_read, \
                          open("proxy_bak", 'w', encoding='utf-8') as proxy_bak_write:
                        begin_Flag = 0  # 设置获取目标内容的flag标志
                        end_Flag = 0  # 设置限制目标内容循环的标志
                        for line in proxy_read.readlines():
                            if line.strip() == "backend %s" % add_domain_name:  # 若其中一行的内容为“backend domain_name",更改获取内容表示符的值为1
                                begin_Flag = 1
                            # 更改获取表示符之后,继续循环表示列表,若碰到以“backend”开头的行,重新将开始标志位设置为0
                            elif line.strip().startswith("backend"):
                                begin_Flag = 0
                            if begin_Flag == 0: # 若获取内容的表示符为0 表示非目标内容,直接写入到proxy_bak文件。
                                proxy_bak_write.writelines(line);
                            elif begin_Flag == 1 and end_Flag == 0:
                                proxy_bak_write.write("backend %s\n" % add_domain_name)
                                for index,domain_info in enumerate(info_list):
                                    info_list[index] == '%s%s\n'%(8*" ",domain_info)
                                proxy_bak_write.writelines(info_list)
                                proxy_bak_write.write('\n')  # 最后加一个空白行
                                end_Flag = 1  # 设置限制目标内容表示符为1
                        os.rename("proxy", "proxy.bak_%s" % bak_time)
                        os.rename("proxy_bak", "proxy")
                        with open("proxy.log", "a+",encoding='utf-8') as log_write:
                            log_write.write("%s add the %s into %s proxy config\n" % (current_time, add_domain_server_info,\
                            add_domain_name))
            break
    else:
        print("您输入的格式不正确,请重新输入!")
# 删除域名信息
def del_backend(del_domain_name):
    '''
    :param del_domain_name:
    :return: None
    '''
    with open("proxy", 'r', encoding='utf-8') as proxy_read, \
            open("proxy_bak", 'w',encoding='utf-8') as proxy_bak_write:
        begin_Flag = 0
        for line in proxy_read.readlines():
            line = line.strip()
            if "backend %s" %del_domain_name == line:
                begin_Flag == 1
            elif line.startswith("backend"):
                begin_Flag = 1
            if begin_Flag == 0 :
                proxy_bak_write.write(line)
    with open("proxy.log",'a+',encoding='utf-8') as log_write:
        log_write.write("%s del the %s info!\n"% (current_time, del_domain_name))
    os.rename("proxy","proxy.bak_%s" %(bak_time))
    os.rename("proxy.bak","proxy")
    print("%s's info is successfully deleted!" % del_domain_name)
# 主程序
def main():
    '''

    :return: none
    '''
    while True:
        print('''
        1.查询
        2.增加
        3.删除
        4.退出
        ''')
        user_choose = input("请输入您的选择:")
        if user_choose.isdigit():
            user_choose = int(user_choose)
            if user_choose == 1:
                search_domain_name = input("请输入您要查询详细的域名:")
                info_list = search_backend(search_domain_name)
                if len(info_list) == 0:
                    print("The info of %s don't exist" % search_domain_name)
                else:
                    for line in info_list:
                        print('\033[31;1m%s\033[0m' % line)
            elif user_choose == 2:
                add_backend()
            elif user_choose == 3:
                del_domain_name = input("input the domain name you want to delete:")
                info_list = search_backend(del_domain_name)
                if len(info_list) == 0:
                    print("要删除的域名信息不存在,不执行任何操作!")
                else:
                    del_backend(del_domain_name)
            elif user_choose == 4:
                for i in range(3):
                    print("程序在\033[31;1m[%s]\033[0m秒后退出!" % (3-i))
                    time.sleep(1)
                exit()
        else:
            print("您的输入有误,请重新输入:")
main()