1. 程式人生 > >函式、函式引數、常用模組(json、os、time)

函式、函式引數、常用模組(json、os、time)

5.1列表生成式

 

s =[1,2,3,4,5,6,7,8]
for i in s:
    print(i+1)#第一種方式
res = [ i+1 for i in s]
print(res)#第二種方式,這兩種方式的區別是第二種放在一個list內了

 

 

 

s =[1,2,3,4,5,6,7,8]

res = [str(i) for i in s]
print(res)

執行結果:['1', '2', '3', '4', '5', '6', '7', '8']

 

5.2函式

 

def func(a,b):
    res = a+b
    print(res)

def func2(a,b):
    res = a+b
    return res
func(1,2)
res=func2(1,2)
print(res)

上面兩個函式的列印結果都是3,只是func沒有返回值,只是列印了一下,而func2有返回值

 

def get_user():
    s = 'abc,123'
   

username,password = s.split(',')
    return username,password
res=get_user()#返回兩個值也可以用一個變數來接收
print(res)

執行結果:('abc', '123')返回的是一個元組

 

return的作用:1、把函式處理的結果返回2、結束函式,函式裡面遇到return,函式立即結束

 

def get_user():
    s = 'abc,123'
   
username,password = s.split(','

)
    return username,password

def login():
    for i in range(3):
        username, password = get_user()
        user = input('username:')
        pwd = input('password:')
        if username==user and password==pwd:
            print('登入成功')
            return
        else
:
            print('賬號/密碼錯錯誤!')
login()
執行結果是:

username:111

password:222

賬號/密碼錯錯誤!

username:111

password:aaa

賬號/密碼錯錯誤!

username:abc

password:123

登入成功

 

5.3函式引數

def say(word):
    pass#什麼也不相干的話,就直接寫個pass

def say(word='haha'):
    print(word)
say()

執行結果:haha

 

def say(word='haha'):
    print(word)
say('你好')

執行結果:你好

如果呼叫函式時,傳了引數,那麼取傳入的引數;如果不傳引數,就取預設值

 

def mysql(username,password,ip,host=3306):#如果有必傳引數,又有預設值引數,那麼預設值引數要寫在最後面

 

既能讀又能寫的函式:#如果傳入了內容,那麼就是寫檔案,如果沒有傳入內容,就是讀檔案

def op_file(filename,content=None):
    with open(filename,'a+',encoding='utf-8') as fw:
        fw.seek(0)#a+的檔案指標在末尾
        if content:
            fw.write(content)
        else:
            return fw.read()#也可以換成res=fw.read()   return res
op_file('zaozao.txt','媽媽愛早早')

 

需求分析:
1、判斷小數點個數是否為1
2、按照小數點分隔,取到小數點左邊和右邊的值
3、判斷正小數,小數點左邊為整數,小數點右邊為整數
4、判斷負小數,小數點左邊以負號開頭,並且只有一個負號,負號後面為整數,小數點右邊為整數

def is_float(s):
    s=str(s)#分隔這是字串才有的方法
    if s.count('.')==1:#判斷只有一個小數點
        left,right = s.split('.')#以小數點分隔,分隔完以後,用兩個變數接收
        if left.isdigit() and right.isdigit():
            print('正小數')
            return True
        elif
left.startswith('-') and left.count('-')==1 and \
                left[1:].isdigit() and right.isdigit():
                print('負小數')
                return True
   
print('不合法')
    return False
is_float(1)

is_float(0)

is_float(0.5)

is_float(-3.5)

is_float('-s.1')

is_float('--98.9')

is_float('--9s8.9s2')

is_float('6')

 

 

5.4全域性變數

name = '小明'
def a():
    name='hahaha'#區域性變數
    print(name)
def b():
    print(name)#自己裡面找不到變數,使用全域性變數
a()
b()

執行結果是:

hahaha

小明

注意:                                                                       

1、如果是字串、intfloat、元組,需要宣告global

name = '小明'
def a():
    global name#宣告更改的是全域性變數,儘量少使用全域性變數
    name='hahaha'
   
print(name)
def b():
    print(name)#自己裡面找不到變數,使用全域性變數
a()
b()

執行結果:

hahaha

hahaha

 

 

2、如果是list、字典、集合的時候,不用宣告global,即可以使用
stus=[]
def a():
    stus.append('abc')
def b():
    print(stus)
a()
b()

執行結果:['abc']

 

 


money = 500
def test(consume):
    return money - consume
def test1(money):
    return test(money) + money
money = test1(money)
print(money)

執行結果是:500

 

 

def test():
    global a
    a = 5
def test1():
    c = a + 5
    return c
#test()#如果該行被註釋掉,那麼會報錯,如果該行不被註釋,執行結果是10.原因是:被註釋掉的話,test函式僅僅是被定義了而已,麼有被呼叫,就不會有全域性變數,當然報錯
res = test1()
print(res)

 

 

list=[1,1,2,3,4]

下標  0 1 2 3 4
for  in list:
    if i%2!=0:
        list.remove(i)
print(list)

執行結果是:[1, 2, 4]

原因:第一次執行的時候,取到1,1被刪除,此時list列表中剩餘的元素[1,2,3,4],現在的下標變成了0 1 2 3 ,迴圈的時候,下標為0的已經迴圈過了,所以會從下標為1 的開始迴圈。

結論:不要迴圈刪list,會導致結果錯亂

解決方法:定義兩個一樣的列表,迴圈list2,從list1中刪元素

list1=[1,1,2,3,4]
list2=[1,1,2,3,4]#或者list2=list1[:],使用切片的方式複製一個list
for  in list2:#迴圈list2
    if i%2!=0:
        list1.remove(i)#從list1中刪除元素
print(list1)

執行結果:[2, 4]

 

 

list1=[1,1,2,3,4]
list2=list1#這個樣子定義相同的list,麼有效果,因為記憶體地址是一樣的
for  in list2:#迴圈list2
    if i%2!=0:
        list1.remove(i)#從list1中刪除元素
print(list1)
print(id(list1))
print(id(list2))

執行結果:

[1, 2, 4]

2102194967176

2102194967176

 

 

 

淺拷貝:兩個變數指向的是同一塊記憶體地址

深拷貝:是會開闢一個新的記憶體地址,存放資料,就是兩塊不同記憶體。

import copy
    # 0 1 2 3
num1 = [1,1,2,3,4,5,6,7,7,8]
num2 = num1 #淺拷貝,指向的記憶體地址是同一個
#num2 = copy.deepcopy(num1)#深拷貝,就是開闢一塊新的記憶體地址
print(id(num1))
print(id(num2))

執行結果:

2019399340232

2019399340232

 

import copy
    # 0 1 2 3
num1 = [1,1,2,3,4,5,6,7,7,8]
#num2 = num1 #淺拷貝,指向的記憶體地址是同一個
num2 = copy.deepcopy(num1)#深拷貝,就是開闢一塊新的記憶體地址
print(id(num1))
print(id(num2))

執行結果:

2400694669512

2400694669768

5.5可變引數、關鍵字引數

PORT=3306   #如果變數名字全部大寫,就代表常量,值不會變,大家都可以使用。

5.5.1可變引數

def mysql2(*info):
    print(info)
mysql2('user',13345435,00000,'sefsd','sdfds')

執行結果:('user', 13345435, 0, 'sefsd', 'sdfds')   把引數都放在一個元組內了

 

例如:給部門員工發郵件

def send_mail(*email):#習慣性大家都寫*args,但是寫啥都無所謂
   print(email)
send_mail('[email protected]')#傳入幾個就發幾個郵件
send_mail('[email protected]','[email protected]','[email protected]')

 

引數型別:

1、  必填引數,位置引數

2、  預設值引數,非必填

3、  可變引數,非必傳,不限制引數個數,比如說給多個人發郵件,發郵件的人數不確定,就可以

      用可變引數

 

def calc(a,b):
    print(a+b)
    return a+b
list = [1,2]
calc(*list)#把list中的元素解開,再分別傳給函式

執行結果:3

注意:

1、  如果定義函式的時候寫了兩個引數,而list中給了三個引數,那麼執行會報錯,TypeError: calc() takes 2 positional arguments but 3 were given

2、  如果定義函式時寫了三個引數,而list中給了兩個引數,那麼執行會報錯,TypeError: calc() missing 1 required positional argument: 'c'

5.5.2關鍵字引數:使用不多,瞭解即可

關鍵字引數非必填,不限制引數個數,但是會把傳過來的關鍵字引數放到一個字典裡面,傳參的時候,必須得用k=v這樣子來傳

def mysql(**mysql_info):
    print(mysql_info)
mysql()#執行結果是空字典
mysql('ip','user')#報錯,原因是傳過來的引數直接給放在一個字典內,直接這樣傳,分不清key-value
mysql(ip='10.138.11.4',port=3306)#執行結果也是空字典

 

 

def request(url,method,**kwargs):

#兩個星號就表示把傳入的引數放在一個字典裡面,這種方式使用不多,瞭解即可
    print(url)
    print(method)
    print(kwargs)
request('api.nnzhp.cn','get',header='sdfsdfsdf=sdfdsfs',file='/xx/xxx/a.txt')

執行結果:

api.nnzhp.cn

get

{'header': 'sdfsdfsdf=sdfdsfs', 'file': '/xx/xxx/a.txt'}

 

 

def request(url,method,**kwargs):
    print(url)
    print(method)
    print(kwargs)
    if kwargs.get('data'):
        data = kwargs.get('data')
    elif kwargs.get('file'):
        file = kwargs.get('file')
request('api.nnzhp.cn','get',header='sdfsdfsdf=sdfdsfs',file='/xx/xxx/a.txt')

執行結果:

api.nnzhp.cn

get

{'header': 'sdfsdfsdf=sdfdsfs', 'file': '/xx/xxx/a.txt'}

 

 

def mysql(host,user,password,port,charset,sql,db):
    print(host)
    print(user)
    print(password)
    print(port)
    print('連線mysql')
dic = {
    'host':'192.168.1.1',
    'user':'root',
    'password':123456,
    'port':3306,
    'charset':'utf-8',
    'sql':'sql',
    'db':'db'
}
mysql(**dic)#兩個星號會把字典拆開,然後傳給函式。

注意:一個星號拆分的是元組或者list,兩個星號拆分的是字典

執行結果:

192.168.1.1

root

123456

3306

連線mysql

 

5.6常用模組

主要有標準模組、第三方模組、自己寫的模組

模組:一個py檔案就是一個模組

5.6.1標準模組

time模組        random模組

5.6.1.1json模組

import json         #解析json的

json,就是一個字串

import json
#解析json的

json_str = '''
{"name":"
王志華","age":25,"sex":"女"}
'''
#json中必須都是雙引號,不能是單引號
res = json.loads(json_str) #把字串(json串)轉成字典
print(res)
print(type(json_str))
print(type(res))

執行結果:

{'name': '王志華', 'age': 25, 'sex': '女'}

<class 'str'>

<class 'dict'>

 

Json轉成字典,用loads()

字典轉成字串(json),用dumps()

 

 

import json
dic = {'name':"xiaohei","age":18,"password":12345,"sex":"男","addr":"北京"}
res = json.dumps(dic)#把字典變成字串
print(res)
print(type(res))

執行結果:

{"name": "xiaohei", "age": 18, "password": 12345, "sex": "\u7537", "addr": "\u5317\u4eac"}

<class 'str'>

 

 

看不懂,加上ensure_ascii=False就可以了

 

import json
dic = {'name':"xiaohei","age":18,"password":12345,"sex":"男","addr":"北京"}
res = json.dumps(dic,ensure_ascii=False)#把字典變成字串
print(res)
print(type(res))

執行結果:

{"name": "xiaohei", "age": 18, "password": 12345, "sex": "男", "addr": "北京"}

<class 'str'>

 

 

import json
dic = {
    "xiaohei":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
    "馬春波":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
    "王東澤":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
}
res = json.dumps(dic,ensure_ascii=False,indent=4)#把字典變成字串,ascii是為了解決中文的問題,indent是為了解決縮排問題
print(res)
print(type(res))

執行結果:

{

    "xiaohei": {

        "age": 18,

        "password": 12345,

        "sex": "男",

        "addr": "北京"

    },

    "馬春波": {

        "age": 18,

        "password": 12345,

        "sex": "男",

        "addr": "北京"

    },

    "王東澤": {

        "age": 18,

        "password": 12345,

        "sex": "男",

        "addr": "北京"

    }

}

<class 'str'>

 

 

5.6.1.2.1     loadsload

 

import json
dic = {
    "xiaohei":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
    "馬春波":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
    "王東澤":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
}
f = open('user.json',encoding='utf-8')
res = json.loads(f.read())#把字串轉成字典
print(res)

執行結果:

{'xiaohei': {'age': 18, 'password': 12345, 'sex': '男', 'addr': '北京'}, '馬春波': {'age': 18, 'password': 12345, 'sex': '男', 'addr': '北京'}, '王東澤': {'age': 18, 'password': 12345, 'sex': '男', 'addr': '北京'}}

 

 

import json
dic = {
    "xiaohei":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
    "馬春波":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
    "王東澤":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
}
f = open('user.json',encoding='utf-8')
res = json.load(f)#load是操作檔案的,直接傳檔名就行
print(res)

執行結果:

{'xiaohei': {'age': 18, 'password': 12345, 'sex': '男', 'addr': '北京'}, '馬春波': {'age': 18, 'password': 12345, 'sex': '男', 'addr': '北京'}, '王東澤': {'age': 18, 'password': 12345, 'sex': '男', 'add r': '北京'}}

 

總結:loads:要先讀出來,然後把字串轉成字典

Load:直接操作檔案

 

 

5.6.1.2.2再來試試dumpsdump

 

import json
dic = {
    "xiaohei":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
},
    "馬春波":{
        "age":18,
        "password":12345,
        "sex":"男",
        "addr":"北京"
   
}
}
#dump 自己寫的
fw = open('newuser.json','w')
json.dump(dic,fw,indent=4,ensure_ascii=False)

 

 

5.6.1.2      os模組

5.6.1.3     time模組

 

 

5.6.2第三方模組:別人已經寫好了,我們安裝就行了

連mysql模組,xpinyin模組

5.6.3自己寫的模組