第4天,函數(shù)進(jìn)階

[toc]

一、函數(shù)對(duì)象

在python中,函數(shù)是一等對(duì)象,“一等對(duì)象”滿足下述條件的程序?qū)嶓w:

  • 可以被引用
  • 可以當(dāng)作參數(shù)傳遞給函數(shù)
  • 能做為函數(shù)的返回結(jié)果
  • 可以當(dāng)作容器數(shù)據(jù)類型的元素,例如:可以當(dāng)作字典中某個(gè)key的value
  • 在運(yùn)行時(shí)創(chuàng)建

1.可以被引用

def foo():
    print('from foo')

func=foo

print(foo)
print(func)
func()

# 輸出:
<function foo at 0x0000000000BAE1E0>
<function foo at 0x0000000000BAE1E0>
from foo

2. 可以當(dāng)作參數(shù)傳遞給另一個(gè)函數(shù)

def foo():
    print('from foo')

def bar(func):
    print(func)
    func()         # 此時(shí)func() == foo()

bar(foo)           #將函數(shù)foo內(nèi)存對(duì)象當(dāng)做參數(shù)傳給bar()

# 輸出:
<function foo at 0x000000000114E1E0>
from foo

3.可以當(dāng)作一個(gè)函數(shù)的返回結(jié)果

def foo():
    print('from foo')

def bar(func):
    return func

f=bar(foo)       # 此時(shí)f = foo

print(f)
f()         # 此時(shí)執(zhí)行f() 相當(dāng)于執(zhí)行foo()

# 輸出:
<function foo at 0x0000000000B8E1E0>
from foo

4. 當(dāng)作其他容器類型數(shù)據(jù)的元素

def foo():
    print('from foo')
    
dic={'func':foo}   # 定義一個(gè)字典dic,將函數(shù)foo的內(nèi)存對(duì)象做為value

print(dic['func'])  # 相當(dāng)于打印foo的內(nèi)存對(duì)象
dic['func']()       # 相當(dāng)于執(zhí)行foo()函數(shù)

# 輸出:
<function foo at 0x0000000000A4E1E0>
from foo

應(yīng)用:

def select(sql):
    print('========>select')

def insert(sql):
    print('========>add')

def delete(sql):
    print('=======>delete')

def update(sql):
    print('=======>update')


func_dic={
    'select':select,
    'update':update,
    'insert':insert,
    'delete':delete
}    # 定義一個(gè)字典,將上面定義的函數(shù)名做為value

def main():
    while True:
        sql = input('>>: ').strip()
        if not sql:continue
        l = sql.split()       
        cmd=l[0]
        if cmd in func_dic:
            func_dic[cmd](l)

main()

二、函數(shù)嵌套

1. 函數(shù)的嵌套定義

簡(jiǎn)單理解就是在定義一個(gè)函數(shù)時(shí),函數(shù)體內(nèi)又定義一個(gè)子函數(shù),示例如下:

def f1():
    def f2():
        print('from f2')
        def f3():
            print('from f3')
        f3()
    f2()
f1()

# 輸出:
from f2
from f3

2. 嵌套函數(shù)的調(diào)用

下面示例是一個(gè)求4個(gè)數(shù)中最大值的小程序:

# 嵌套函數(shù)
def mymax(x,y):
    return x if x > y else y

def four(a,b,c,d):
    res1=mymax(a,b)  # 調(diào)用mymax()函數(shù)先比較a和b,較大的值給res1    
    res2=mymax(c,res1)
    res3=mymax(d,res2)
    return res3

print(four(8,45,9,34))

# 輸出:
45

三、名稱空間與作用域

1.定義名字的方法

  • 導(dǎo)入的模塊名稱time,如:import time
  • 定義變量的名稱name,如:name = 'caigy'
  • 定義函數(shù)的名稱func,如:
def func():
    pass
  • 定義類的名稱foo,如:
class foo:
    pass

2. 三種名稱空間

2.1 內(nèi)置名稱空間

隨著Python解釋器的啟動(dòng)而產(chǎn)生,比如python內(nèi)置的一些函數(shù):sun()、max()、min()等,這些函數(shù)隨著python的啟動(dòng)就定義好了,所以在定義名稱時(shí)不要與這些關(guān)鍵字重名
可以用以下方法查看python的內(nèi)置函數(shù):

import builtins
for i in dir(builtins):
    print(i)
2.2 全局名稱空間

py文件的執(zhí)行會(huì)產(chǎn)生全局名稱空間,指的是文件級(jí)別定義的名字都會(huì)放入該空間

2.3 局部名稱空間

調(diào)用函數(shù)時(shí)會(huì)產(chǎn)生局部名稱空間,只在函數(shù)調(diào)用時(shí)臨時(shí)綁定,函數(shù)調(diào)用結(jié)束后解除綁定。

如下示例:

# !/user/bin/env python
# -*- coding:utf-8 -*-

name = 'caigy'   # 1

def func():
    x = 1        # 2

代碼中:

  1. 變量name是全局名稱空間
  2. 變量x在函數(shù)func()中,是局部名稱空間

3. 作用域

  • 全局作用域:內(nèi)置名稱空間、全局名稱空間
  • 局部作用域:局部名稱空間

python中名字的查找順序:
局部名稱空間 ---> 全局名稱空間 ---> 內(nèi)置名稱空間

  • 查看全局作用域內(nèi)的名字: globals()
  • 查看局部作用域內(nèi)的名字: locals()

示例代碼:

name = 'caigy'
def foo():
    name = 'egon'
    print(name)
    print(locals())
    print(globals())
foo()

以上代碼輸出結(jié)果:

egon
{'name': 'egon'}
{'__file__': 'D:/PycharmProjects/s17/day04/test.py', 'foo': <function foo at 0x013B5660>, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x01755A90>, 'name': 'caigy', '__name__': '__main__', '__spec__': None, '__package__': None, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__cached__': None}

作用域的有效范圍

  • 全局作用域的名字:全局有效,在任何位置都能被訪問(wèn)到,除非del刪掉,否則會(huì)一直存活到文件執(zhí)行完畢
  • 局部作用域的名字:局部有效,只能在局部范圍內(nèi)調(diào)用,只在函數(shù)調(diào)用時(shí)才有效,調(diào)用結(jié)束就失效

注:當(dāng)全局變量與局部變量同名時(shí),在定義局部變量的子程序內(nèi),局部變量起作用;在其它地方全局變量起作用

四、閉包函數(shù)

閉包函數(shù)的特性:

  • 定義在一個(gè)函數(shù)的內(nèi)部的函數(shù)
  • 包含對(duì)外部作用域而非全局作用域的引用

該內(nèi)部函數(shù)就稱為閉包函數(shù)
如下示例:

def func():
    name = 'caigy'
    def foo():
        print(name)
    return foo

f = func()  # func()返回結(jié)果是foo ,所以f = foo
print(f)    # 打印的實(shí)際上是foo的內(nèi)存對(duì)象地址
f()

# 輸出結(jié)果:
<function func.<locals>.foo at 0x01342150>
caigy

如上述代碼中,foo()就是一個(gè)閉包函數(shù)

閉包函數(shù)的應(yīng)用:隨性計(jì)算
爬取一個(gè)網(wǎng)頁(yè)

from urllib.request import urlopen

def index(url):
    def get():
        return urlopen(url).read()
    return get

f= index('http://www.360duohui.com')
res = f().decode('utf-8')
print(res)

上述代碼中g(shù)et()函數(shù)就是一個(gè)閉包函數(shù)

總結(jié):閉包函數(shù)實(shí)現(xiàn)了內(nèi)部函數(shù)在外部可以被調(diào)用

獲取閉包函數(shù)所引用的外部變量(非全局變量)的值

def func():
    name='caigy'
    def foo():
        print(name)
    return foo
f = func()
print(f.__closure__[0].cell_contents)

# 輸出:
caigy

五、裝飾器(decorator)

裝飾器,顧名思義,就是用來(lái)裝飾用的,具體點(diǎn)說(shuō)就是給其它程序添加功能的。其本質(zhì)就是函數(shù),功能是為其他函數(shù)添加新功能。

裝飾器本身可以是任何可調(diào)用對(duì)象,被裝飾的對(duì)象也可以是任意可調(diào)用的對(duì)象。

1. 為什么要用裝飾器呢?

源于程序開(kāi)的開(kāi)放封裝原則:

  • 對(duì)修改是封閉的,對(duì)擴(kuò)展是開(kāi)放的。
  • 裝飾器就是為了在不修改被裝飾對(duì)象的源代碼以及調(diào)用方式的前提下,為其添加新功能

如下示例:

def run():
    time.sleep(3)
    print('already test 3s')
run()

為上述代碼添加一個(gè)打印日志的功能:
無(wú)參裝飾器

import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        func()     #3
        stop_time = time.time()
        print('run is %ss'%(stop_time-start_time))
    return wrapper

timer       #1
def run():
    time.sleep(3)
    print('already test 3s')
run()       #2

#1 @timer 實(shí)際上就是做了run = timer(run) 的操作;
#2 因?yàn)閠imer()函數(shù)的返回值是wrapper,所以此時(shí)的run = wrapper , 所run()實(shí)際就相當(dāng)于調(diào)用了wrapper()
#3 run 做為參數(shù)傳給timer()函數(shù),所以此時(shí)func=run,此時(shí)的func()相當(dāng)于調(diào)用了run()

以上代碼的輸出結(jié)果如下:

already test 3s
run is 3.0033679008483887s

2. 附加多個(gè)裝飾器

有參裝飾器

import time
def timer(func_1):
    def wrapper_1(*args,**kwargs):
        start_time = time.time()
        func_1(*args,**kwargs)      #3
        stop_time = time.time()
        print('run is %s秒 '%(stop_time-start_time))
    return wrapper_1

user_stat = {'name':None,'stats':False}
def auth(func):
    def wrapper(*args,**kwargs):
        if user_stat['name'] and user_stat['stats']:
            print('login successful')
            func(*args, **kwargs)
        else:
            name = input('name: ')
            pwd = input('password: ')
            if name == 'egon' and pwd == '123':
                # 登錄成功后記錄用戶名和登錄狀態(tài),下次調(diào)用時(shí)就不用再輸入用戶名登錄了
                user_stat['name'] = 'egon'
                user_stat['stats'] = True
                print('login successful')
                func(*args,**kwargs)
                # time.sleep(3)
            else:
                print('login error')
    return wrapper

@timer   #2
@auth    #1  
def index():
    print('Welcome to Oldboyedu.com')

@auth
def home(name):
    print('Welcome to %s homepage'%name)

index()   #4
home('egon')

輸出結(jié)果:

name: egon
password: 123
login successful
Welcome to Oldboyedu.com
run is 3.2893900871276855秒 
login successful
Welcome to egon homepage

#1 @auth 實(shí)際上就是做了index = auth(index)的操作,因?yàn)閍uth()函數(shù)的返回值是wrapper,所以index此時(shí)等于wrapper,在下方加括號(hào)()就可以直接調(diào)用wrapper()函數(shù)了
#2 由于此時(shí)@auth 為wrapper, 所以@timer 就是wrapper = timer(wrapper) , timer()的返回值是wrapper_1,所以此時(shí)wrapper = wrapper_1
#3 由于wrapper被當(dāng)作參數(shù)傳給timer(),所以此時(shí)func_1 = wrapper
#4 在執(zhí)行index()時(shí),相于當(dāng)于執(zhí)行wrapper_1() ;當(dāng)程序執(zhí)行到func_1(args,*kwargs)時(shí),此時(shí)的func_1 就是 wrapper,所以就會(huì)調(diào)用wrapper(args,*kwargs);當(dāng)wrapper()函數(shù)內(nèi)的程序執(zhí)行到func(args,*kwargs)時(shí),此時(shí)的func = index ,所以用調(diào)用真實(shí)定義的index()函數(shù);然后返回wrapper_1(),繼續(xù)執(zhí)行func_1()后的代碼。

六、迭代器(iterator)

1. 迭代的概念

重復(fù)的過(guò)程稱為迭代,每次重復(fù)即為一次迭代,并且每次迭代的結(jié)果作為下一次迭代的初始值;
不是迭代:

while True: #只滿足重復(fù),因而不是迭代
    print('====>')

下面才為迭代

l = [1, 2, 3]
count = 0
while count < len(l):  
    print('====>', l[count])
    count += 1

# 輸出:
====> 1
====> 2
====> 3

注:以上這種方式迭代的是列表,而列表是有序的對(duì)象,那像無(wú)序的對(duì)象,比如:字典,集合,文件等如何迭代呢?

2. 為什么要有迭代器

對(duì)于沒(méi)有索引的數(shù)據(jù)類型,必須提供一種不依賴索引的迭代方式
可迭代的對(duì)象:內(nèi)置__iter__方法的對(duì)象,都是可迭代的對(duì)象

[1,2].__iter__()        # 列表
'hello'.__iter__()      # 字符串
(1,2,).__iter__()       # 元組
{'a':1,'b':2}.__iter__()    # 字典
{1,2,3}.__iter__()      # 集合

迭代器: 執(zhí)行__iter__方法,得到的結(jié)果就是迭代器,迭代對(duì)象都具體__next__方法

i = [1,2,3].__iter__()
print(i)    # 打印可迭代對(duì)象的內(nèi)存地址

print(i.__next__())
print(i.__next__())
print(i.__next__())
print(i.__next__())   
    # 超出迭代的對(duì)象個(gè)數(shù)后會(huì)拋出異常:StopIteration

# 輸出:
<list_iterator object at 0x011B5AB0>
1
2
3
Traceback (most recent call last):
  File "D:/PycharmProjects/s17/day04/test.py", line 209, in <module>
    print(i.__next__())
StopIteration

迭代字典

i={'a':1,'b':2,'c':3}.__iter__()

print(i.__next__())     # 迭代字典中的key
print(i.__next__())
print(i.__next__())
print(i.__next__())  
    # 超出字典i中的鍵值對(duì)的個(gè)數(shù),會(huì)拋出異常:StopIteration

換一種方法:

i={'a':1,'b':2,'c':3}
I = iter(i)

print(next(I))
print(next(I))
print(next(I))

注:__iter__() = iter(),__next__() = next(),兩種方法得到的結(jié)果是一樣的。

利用while循環(huán)迭代字典

dic={'a':1,'b':2,'c':3}
i=dic.__iter__()   # 生成迭代器對(duì)象
while True:
    try:
        key=i.__next__()
        print(dic[key])
    except StopIteration:  # 遇到指定異常后,執(zhí)行子代碼
        break

3. 如何判斷一個(gè)對(duì)象是可迭代對(duì)象,還是迭代器對(duì)象

  • 可迭代對(duì)象:只有__iter__方法,執(zhí)行該方法得到的是迭代器對(duì)象
  • 迭代器對(duì)象:有__next__方法和__iter__方法,迭代器對(duì)象執(zhí)行__iter__方法,得到的結(jié)果仍然是它本身。

判斷可迭代的對(duì)象需要導(dǎo)入Iterable模塊

from collections import Iterable,Iterator

f = open('a.txt','w')
f.__iter__()

# 下列數(shù)據(jù)類型都是可迭代的對(duì)象
print(isinstance('abc',Iterable))       # 字符串
print(isinstance([1,2,3],Iterable))     # 列表
print(isinstance({'a':1,},Iterable))    # 字典
print(isinstance({1,2,3},Iterable))     # 集合
print(isinstance((1,2,),Iterable))      # 元組
print(isinstance(f,Iterable))           # 文件    

# 輸出:
True
True
True
True
True
True

判斷迭代器對(duì)象需要導(dǎo)入Iterator模塊

from collections import Iterable,Iterator

f = open('a.txt','w')
f.__iter__()

# 只有文件是迭代器對(duì)象
print(isinstance('abc',Iterator))
print(isinstance([],Iterator))
print(isinstance((),Iterator))
print(isinstance({'a':1},Iterator))
print(isinstance({1,2},Iterator))
print(isinstance(f,Iterator))

# 輸出:
False
False
False
False
False
True

驗(yàn)證迭代器對(duì)執(zhí)行__iter__方法得到的結(jié)果仍然是其本身

f = open('a.txt','w')
f1 = f.__iter__()
print(f)
print(f1)
print(f1 is f)      # 輸出`True`表示結(jié)論正確 

# 輸出:
<_io.TextIOWrapper name='a.txt' mode='w' encoding='cp936'>
<_io.TextIOWrapper name='a.txt' mode='w' encoding='cp936'>
True

4. 迭代器的優(yōu)點(diǎn)和缺點(diǎn)

其特點(diǎn):

  • 訪問(wèn)者不需要關(guān)心迭代器內(nèi)部的結(jié)構(gòu),僅需通過(guò)next()方法不斷去取下一個(gè)內(nèi)容
  • 不能隨機(jī)訪問(wèn)集合中的某個(gè)值 ,只能從頭到尾依次訪問(wèn)
  • 訪問(wèn)到一半時(shí)不能往回退
  • 便于循環(huán)比較大的數(shù)據(jù)集合,節(jié)省內(nèi)存

  • 優(yōu)點(diǎn):

    • 提供了一種不依賴于下標(biāo)的迭代方式
    • 就迭代器本身來(lái)說(shuō),更節(jié)省內(nèi)存
  • 缺點(diǎn):

    • 無(wú)法獲取迭代器對(duì)象的長(zhǎng)度
    • 不如序列類型的數(shù)據(jù)取值靈活,而且是一次性的,只能往后取值,不能往前退

      驗(yàn)證:只能往后取值,不能往前退

        l=[10000,2,3,4,5]
        i=iter(l)
        for item in i:
            print(item)
        print('=====================')
        
        for item in i:
            print(item)
        
        # 輸出:
        10000
        2
        3
        4
        5
        ====================
        # 通過(guò)上述代碼 的結(jié)果可以看出,通過(guò)列表l生成的迭代器i ,通過(guò)for循環(huán)迭代后,再次通過(guò)for循環(huán)迭代,就取不到值了

擴(kuò)展:enumerate()方法生成的也是迭代器對(duì)象

l=[2,3,4]

i=enumerate(l)

print(next(i))
print(next(i))
print(next(i))

# 輸出:
(0, 2)
(1, 3)
(2, 4)

總結(jié):python中for循環(huán)就是通過(guò)迭代器的方式來(lái)實(shí)現(xiàn)的,而while只是普通的循環(huán),for迭代 == while + try ... except(異常處理)

七、生成器(generator)

只要函數(shù)體內(nèi)包含yield關(guān)鍵字,該函數(shù)就是生成器函數(shù)

1. 生成器簡(jiǎn)單示例

生成器就是迭代器

def index():
    print('first')
    yield 1
    print('second')
    yield 2
    print('third')
    yield 3

g = index()
for i in g:
    print(i)

上述代碼輸出:

first
1
second
2
third
3

通過(guò)next()方法:

def index():
    print('first')
    yield 1
    print('second')
    yield 2
    print('third')
    yield 3

g = index()
print(next(g))  # next()方法觸發(fā)迭代器g的執(zhí)行,進(jìn)而觸發(fā)函數(shù)的執(zhí)行
print(next(g))
print(next(g))

# 輸出:
first
1
second
2
third
3

生成器應(yīng)用 :

def counter(n):
    print('start...')
    i=0
    while i < n:
        yield i
        i+=1
    print('end...')

g=counter(5)
print(g)    # 這一步不會(huì)執(zhí)行counter()函數(shù),如果是普通函數(shù),就會(huì)被執(zhí)行
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

# 輸出:
<generator object counter at 0x0196DB10>
start...
0
1
2
3
4

注:上述代碼中,迭代器對(duì)象g,只有通過(guò)next()方法(調(diào)用時(shí),才會(huì)觸發(fā)函數(shù)counter()的執(zhí)行

總結(jié):
yield的功能:

  • 相當(dāng)于為函數(shù)封裝好__iter____next__
  • return只返回一次值,函數(shù)就終止了,而yield能返回多次值,每次返回都會(huì)將函數(shù)暫停,下一次next()會(huì)從上一次暫停的位置繼續(xù)執(zhí)行

2. 生成器執(zhí)行流程

def foo():
    print('in the foo ...')
    food = yield '您好'
    print('food >>>',food)
    print('我在后面')
    food1= yield '你壞'
    print('food1 >>> ',food1)

g= foo()
res = next(g)
print(res)
res1 = g.send('x')
print(res1)
##res2= g.send('xx')

'''
生成器執(zhí)行流程:
1.g=foo(),只是將foo()生成器對(duì)象賦值給g,然后繼續(xù)往下執(zhí)行;

2.遇到next()或g.send('x')就開(kāi)始執(zhí)行foo()內(nèi)部的代碼,\
  執(zhí)行遇到第一個(gè)yield時(shí),就暫停(我也理解為進(jìn)入休眠狀態(tài)),\
  并將yield后面的值返回給next(g),并跳出到foo()外面next(g)所在的那一行,\
  將yield返回的值賦值給res

3.res接收yield返回給next(g)的值,然后往下執(zhí)行代碼,打印res的值;

4.當(dāng)再次遇到next()或g.send('x')時(shí),喚醒foo()繼續(xù)從上次 \
  暫停的位置開(kāi)始執(zhí)行, 同時(shí)將g.send(‘x’)中的'x'發(fā)送 \
  給第一個(gè)yield,并賦值給food,然后繼續(xù)往下執(zhí)行;

5.當(dāng)遇到第二個(gè)yield時(shí),進(jìn)入暫停(休眠),\
  同時(shí)將yield后面的值返回給g.send('x'),\
  跳出到g.send('x')所在的那一行,并將yield返回的值賦值給res1,\
  然后繼續(xù)執(zhí)行至結(jié)束。
    
注意:
    print(res1)后面沒(méi)有代碼了,此時(shí)foo()中的food1是空,\
    如果print(res1)后面再出現(xiàn)g.send('xx')代碼,\
    才會(huì)將'xx'發(fā)送給第二個(gè)yield,并賦值給food1;
    但是,foo()內(nèi)部會(huì)從第二個(gè)yield那一行繼續(xù)往下執(zhí)行,\
    如果后面沒(méi)有yield關(guān)鍵字了,程序就會(huì)拋出一個(gè)StopIteration異常。
'''

生成器的應(yīng)用:
實(shí)現(xiàn)Linux命令tail -f a.txt | grep 'python'的功能

import time
def tail(filepath):
    with open(filepath,encoding='utf-8') as f:
        f.seek(0,2)     # 跳到文件末尾
        while True:
            line=f.readline().strip()
            if line:
                yield line      #3
            else:
                time.sleep(0.2)

def grep(pattern,lines):        #1
    for line in lines:          #2
        if pattern in line:     #4
            yield line          #5

g=grep('python',tail('a.txt'))
print(g)

for i in g:                     #6
    print(i)

程序解析:
#1 pattern = 'python' , lines = tail('a.txt')
#2 此時(shí)的lines是一個(gè)迭代器,經(jīng)過(guò)for循環(huán)會(huì)觸發(fā)tail('a.txt')函數(shù)的執(zhí)行,這時(shí)運(yùn)行tail()函數(shù)內(nèi)的程序,會(huì)通過(guò)while循環(huán)監(jiān)控文件末尾是否有內(nèi)容
#3 如果有新內(nèi)容,則通過(guò)yield返回
#4 第#3通過(guò)yield返回的line傳給#4行的line
#5 這里將line通過(guò)yield返回給#6
#6 這時(shí)i = line

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本文翻譯自Functional Programming Howto 本文將介紹Python中函數(shù)式編程的特性。在對(duì)...
    大蟒傳奇閱讀 2,651評(píng)論 4 14
  • 教程總綱:http://www.runoob.com/python/python-tutorial.html 進(jìn)階...
    健康哥哥閱讀 2,079評(píng)論 1 3
  • 內(nèi)置函數(shù)Python解釋器內(nèi)置了許多功能和類型,總是可用的。他們是按字母順序列在這里。 abs(x)返回一個(gè)數(shù)的絕...
    uangianlap閱讀 1,273評(píng)論 0 0
  • 基礎(chǔ)1.r''表示''內(nèi)部的字符串默認(rèn)不轉(zhuǎn)義2.'''...'''表示多行內(nèi)容3. 布爾值:True、False(...
    neo已經(jīng)被使用閱讀 1,732評(píng)論 0 5
  • 第二課主要練習(xí)打招呼。不過(guò)30分鐘課程前10分鐘和后面穿插的5分鐘都在用來(lái)復(fù)習(xí)第一課,所以新內(nèi)容不是很多。 Fre...
    layilayo閱讀 326評(píng)論 0 2