欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

python 函数初级

一. 什么是函数

python中我们把需要复用的代码块使用关键字def包含定义为一个新的对象,这个对象就叫做函数。

函数特性:

  1.可读性强,复用性强

  2.def关键字声明函数

  3.函数必须新定义后调用

  4.函数名命名规则参考变量命名规则,建议使用下划线命名法,或者驼峰命名法。
import os,pathlib

def register():
    """
    提供用户注册,每个用户存在3个字段,用户名,密码,密码错误次数,进行用户名已存在的验证,对用户文件进行两次文件操作。
    :param
    :return: "注册成功"
    """
    while True:
        user = input("请输入用户名:").strip()
        #以r模式打开文件,读取信息进行用户名已存在验证,以a模式对注册成功的用户进行写入文件。
        if not os.path.exists("user_info.txt"):         #如果用户文件不存在,则创建空的文件,使用pathlib模块
            pathlib.Path("user_info.txt").touch()
        with open('user_info.txt', 'r') as f1, open("user_info.txt", 'a') as f2:
            tmp = []
            for i in f1.readlines():
                tmp.append(i.split()[0])
            if user in tmp:
                print("用户名已被注册,请重新输入:")
                continue
            while True:
                passwd1 = input("请输入密码").strip()
                passwd2 = input("请确认密码").strip()
                lock_num = "0"
                if passwd1 == passwd2:
                    f2.write(user+"\t"+passwd1+"\t"+lock_num+"\n")
                    return "注册成功!"
                else:
                    print("两次输入的密码不一致,请重新输入!")


def login():
    """
    用户登录认证,使用readline进行逐行读取,对读取到的数据进行验证,lock_num此处逻辑为用户在用户名输入正确,
    密码错误的情况下,对用户文件密码错误次数进行操作+1,达到3此锁定账户,达到3次之前输入正确密码则清除密码错
    误次数
    :return: (用户操作返回信息,操作完成后状态码(stat))
    :stat: 0        登陆成功
           1        登陆失败,账户没有被锁定
           2        账户已被锁定,或者当前输入密码错误次数到达3次,账户被锁定
    """
    user = input("请输入用户名:").strip()
    pwd = input("请输入密码:").strip()
    with open("user_info.txt", "r") as f:
        while True:
            info = f.readline()
            if info:
                u, p, lock= info.split()
                if lock != "3":
                    if u == user and p == pwd:
                        lock_user(user, 0)
                        return ("登录成功!",0)
                    elif u == user and p != pwd:
                        lock_num = lock_user(user, 1)
                        if lock_num < 3:
                            return ("密码错误,错误次数达到3次将锁定账户,你还有%s次机会"%(3-lock_num),1)
                        else:
                            return ("由于密码输入错误次数过多,你的账户已被锁定,请联系管理员!",2)
                else:
                    return ("你的账户已被锁定!,请联系管理员",2)
            else:
                return ("用户名不存在,请重新输入!",1)




def lock_user(user, stat):
    """
    根据传入的用户名对用户文件进行操作。
    :stat:  0       清零用户密码输入错误次数
            1       用户密码输入错误次数+1
            2       删除用户
    :param user:    用户名
    :param stat:    操作状态码
    :return: stata 为0 1 是返回密码输入错误次数。
             stat 为2时,返回用户删除成功提示。
    """
    with open("user_info.txt", "r") as f:
        content = f.readlines()
        for i in content:
            with open("user_info.txt", "w") as f2:
                if user == i.split()[0]:
                    if stat == 2:
                        content.remove(i)
                        f2.writelines(content)
                        return "%s删除成功"%user
                    else:
                        idx = content.index(i)
                        l = i.split()
                        if stat == 1:
                            l[2] = str(int(l[2])+1)
                        elif stat == 0:
                            l[2] = str(0)
                        lock_num = int(l[2])
                        l = "\t".join(l)+"\n"
                        content[idx] = l
                        f2.writelines(content)
                        return lock_num

def rf_user():
    """
    删除用户
    :return:
    """
    uname = input("请输入要删除的用户名:")
    print(lock_user(uname, 2))




s1 = """请选择操作类型:
1.注册
2.登陆
3.删除用户
q.退出
请输入:"""
if __name__ == "__main__":
    flag = True
    while flag:
        choice = input(s1)
        if choice == "1":
            print(register())
        elif choice == "2":
            while flag:
                s, stat = login()
                if stat == 0:
                    print(s)
                    flag = False
                elif stat == 1:
                    print(s)
                elif stat == 2:
                    print(s)
                    break
        elif choice == "q":
            break
        elif choice == "3":
            rf_user()
一个简单的用户登陆管理

二. 定义函数

1.如何定义函数

#语法
def 函数名(参数1,参数2,参数3,...):
    '''注释'''
    函数体
    return 返回的值

#函数名要能反映其意义

2.定义函数的三种形式

#1、无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印
#2、有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值
#3、空函数:设计代码结构
#定义阶段
def tell_tag(tag,n): #有参数
    print(tag*n)

def tell_msg(): #无参数
    print('hello world')

#调用阶段
tell_tag('*',12)
tell_msg()
tell_tag('*',12)

'''
************
hello world
************
'''

#结论:
#1、定义时无参,意味着调用时也无需传入参数
#2、定义时有参,意味着调用时则必须传入参数

无参、有参
有参,无参
def auth(user,password):                             
    '''                                                           
    auth function                                                 
    :param user: 用户名                                              
    :param password: 密码                                           
    :return: 认证结果                                                 
    '''                                                           
    pass                                                          
                                                                  
def get(filename):                                                
    '''                                                           
    :param filename:                                              
    :return:                                                      
    '''                                                           
    pass                                                          
                                                                  
def put(filename):                                                
    '''                                                           
    :param filename:                                              
    :return:                                                      
    '''                                                           
def ls(dirname):                                                  
    '''                                                           
    :param dirname:                                               
    :return:                                                      
    '''                                                           
    pass                                                          

#程序的体系结构立见           

空函数
空函数

三.调用函数

1.调用函数

函数的调用:函数名加括号
1 先找到名字
2 根据名字调用代码

2.返回值

无return->None
return 1个值->返回1个值
return 逗号分隔多个值->元组
什么时候该有返回值?
    调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
    通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
什么时候不需要有返回值?
    调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
    通常无参函数不需要有返回值

3.函数调用的三种方式

1 语句形式:foo()
2 表达式形式:3*len('hello')
3 当中另外一个函数的参数:range(len('hello'))

四. 函数的参数

1.形参和实参

#形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
#形参位置的*,**: 聚合
#实参位置的*,**: 打散
 

2.具体应用

#1、位置参数:按照从左到右的顺序定义的参数
        位置形参:必选参数
        位置实参:按照位置给形参传值

#2、关键字参数:按照key=value的形式定义的实参
        无需按照位置为形参传值
        注意的问题:
                1. 关键字实参必须在位置实参右面
                2. 对同一个形参不能重复传值

#3、默认参数:形参在定义时就已经为其赋值
        可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
        注意的问题:
                1. 只在定义时赋值一次
                2. 默认参数的定义应该在位置形参右面
                3. 默认参数通常应该定义成不可变类型


#4、可变长参数:
        可变长指的是实参值的个数不固定
        而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs

        ===========*args===========
        def foo(x,y,*args):
            print(x,y)
            print(args)
        foo(1,2,3,4,5)

        def foo(x,y,*args):
            print(x,y)
            print(args)
        foo(1,2,*[3,4,5])


        def foo(x,y,z):
            print(x,y,z)
        foo(*[1,2,3])

        ===========**kwargs===========
        def foo(x,y,**kwargs):
            print(x,y)
            print(kwargs)
        foo(1,y=2,a=1,b=2,c=3)

        def foo(x,y,**kwargs):
            print(x,y)
            print(kwargs)
        foo(1,y=2,**{'a':1,'b':2,'c':3})


        def foo(x,y,z):
            print(x,y,z)
        foo(**{'z':1,'x':2,'y':3})

        ===========*args+**kwargs===========

        def foo(x,y):
            print(x,y)

        def wrapper(*args,**kwargs):
            print('====>')
            foo(*args,**kwargs)

#5、命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
可以保证,传入的参数中一定包含某些关键字
        def foo(x,y,*args,a=1,b,**kwargs):
            print(x,y)
            print(args)
            print(a)
            print(b)
            print(kwargs)

        foo(1,2,3,4,5,b=3,c=4,d=5)
        结果:
            1,2
            (3, 4, 5)
             1
            3
            {'c': 4, 'd': 5}

此乃重点知识!!!    
重点知识

3.一些函数实例

import chardet,os
def get_code(file_name):                
    """
    获取文本文件的字符编码
    :param file_name: 文件名
    :return: 返回编码字符串
    """
    with open(file_name,"rb") as f:
        return chardet.detect(f.read(100))["encoding"]      #chardet模块是第三方模块,需要安装

def modify(f1,old,new):
    """
    替换文件指定的内容
    :param f1: 文件名 
    :param old: 要替换的字符
    :param new: 新的字符
    :return:    没有返回值
    """
    with open(f1, "r", encoding=get_code(f1)) as f, open("tmp", 'w', encoding=get_code(f1)) as t:
        for i in f:
            t.write(i.replace(old,new))
            
    os.remove(f1)
    os.rename("tmp",f1)
# modify("youth.txt","人生啊", "人")
modify("real_gbk.txt","成年","成熟的")
批量修改文件内容
def is_float(num):
    """
    判断用户输入的是否为小数或整数
    :param num: str
    :return: bool
    """
    if (num.startswith("-") and num[1:].isdigit()) or num.isdigit():
        return True
    elif num.count(".") == 1 and not num.startswith(".") and not num.endswith("."):
        li = num.split(".")
        if li[0].startswith("-"):
            if li[0][1:].isdigit() and li[1].isdigit():
                return True
            else:
                return False
        else:
            if li[0].isdigit() and li[1].isdigit():
                return True
            else:
                return False
    else:
        return False
判断字符串是否是整数或小数
def get_host_ip():
    """
    查询本机ip地址
    :return: ip
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip
获取本地服务器IP

 

posted on 2018-08-05 11:31  Louiszj  阅读(165)  评论(0编辑  收藏  举报

导航