05.Python高級編程

1 ==,is的使用

  • is 是比較兩個引用是否指向了同一個對象(地址引用比較)。
  • == 是比較兩個對象是否相等。(比較的數值)

2 深拷貝、淺拷貝、copy.copy

2.1 淺拷貝

淺拷貝:html

  1. 拷貝的是地址引用。能夠找到共同的內容
  2. 一方修改了,另外一方受影響
a = [1,2,3,4]
b = a
print(id(a)) #2540558597256
print(id(b)) #2540558597256
a.append(5)
print(a)     #[1, 2, 3, 4, 5]
print(b)     #[1, 2, 3, 4, 5]

2.2 深拷貝

深拷貝:python

  1. 深拷貝的是內容同樣。地址不同。
  2. 一方修改了,另外一方不受影響
  • b = copy.deepcopy(a)算法

    b獲得的內容與a的內容徹底同樣,地址不同。編程

    就算a中有對象引用,b中對應的引用的對象依然是內容同樣,地址不同。json

    遞歸拷貝緩存

    注意:
    若是是一個不可變對象(內部存儲仍是不可變對象),深拷貝的結果 = 淺拷貝,地址同樣多線程

2.3 copy.copy

copy.copy閉包

  1. copy.copy這個函數結果會由於是可變或者不可變致使結果不一樣
  2. 只能拷貝一層。根據類型有關。若是是列表(可變類型),深拷貝。若是是元組(不可變)淺拷貝
  3. 若是裏面還有嵌套的對象,淺拷貝
  • b = copy.copy(a)
import copy

a = [1,2,3,4]

#至關於深拷貝
b = copy.copy(a)

print(id(a))
print(id(b))
a.append(5)
print(a)
print(b)

print('*'*50)

a = (1,2,3,4)

#至關於淺拷貝
b = copy.copy(a)

print(id(a))
print(id(b))


----------------------------

a = [11,22,33]
b = [44,55,66]
c = [a,b]

d = copy.copy(c)

print(id(c))
print(id(d))
print(c)
print(d)

print('*'*50)

a.append(120)
#c[0].append(120)
print(c)
print(d)

print('*'*50)

a = [11,22,33]
b = [44,55,66]
c = (a,b)

d = copy.copy(c)

print(id(c))
print(id(d))
print(c)
print(d)

print('*'*50)

a.append(120)
#c[0].append(120)
print(c)
print(d)

3 屬性property

3.1私有屬性添加getter和setter方法

私有的內容,對外不能直接訪問。
若是想對外訪問,須要提供能夠訪問的方法,好比這裏的getMoney,setMoney

調用的時候比較麻煩。
能不能像操做屬性同樣呢?

屬性名 = property(get,set)
class Money(object):
    def __init__(self):
        self.__money = 0

    def getMoney(self):
        return self.__money

    def setMoney(self, value):
        if isinstance(value, int):
            self.__money = value
        else:
            print("error:不是整型數字")

m = Money()
print(m.getMoney())
m.setMoney(10)
print(m.getMoney())

3.2 使用property升級getter和setter方法

class Money(object):
    def __init__(self):
        self.__money = 0

    def getMoney(self):
        return self.__money

    def setMoney(self, value):
        if isinstance(value, int):
            self.__money = value
        else:
            print("error:不是整型數字")

    money = property(getMoney,setMoney)


m.money = 120       #至關於上面的m.setMoney(120)
print(m.money)      #至關於上面的m.getMoney
#或者是
print(Money.money)

3.3 使用property取代getter和setter方法

class Money(object):
    def __init__(self):
        self.__money = 0

    @property
    def money(self):
        return self.__money

    @money.setter
    def money(self, value):
        if isinstance(value, int):
            self.__money = value
        else:
            print("error:不是整型數字")

m = Money()
print(m.money)

m.money = 120

print(m.money)

4 生成器

4.1 什麼是生成器

若是列表元素能夠按照某種算法推算出來,那咱們是否能夠在循環的過程當中不斷推算出後續的元素呢?這樣就沒必要建立完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator。app

4.2 建立生成器方法1

要建立一個生成器,有不少種方法。第一種方法很簡單,只要把一個列表生成式的 [ ] 改爲 ( )dom

#列表生成式
ls = [x for x in range(100)]
print(ls)

#生成器
ge = (x**2 for x in range(1000))
print(ge)
print(type(ge))

i = 0
while i<19:
    next(ge)
    i+=1
print(next(ge))

總結

生成器保存的是算法,每次調用 next(G) ,就計算出 G 的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出 StopIteration 的異常。固然,這種不斷調用 next() 實在是太變態了,正確的方法是使用 for 循環,由於生成器也是可迭代對象。因此,咱們建立了一個生成器後,基本上永遠不會調用 next() ,而是經過 for 循環來迭代它,而且不須要關心 StopIteration 異常。

4.3 建立生成器方法2 yield 值

yield 值

  1. 調用函數,獲得一個生成器對象。這個函數沒有執行
  2. next調用1獲得的對象,若是遇到了yield,代碼會阻塞,next的返回值就yield後的值
def fib(times):
    print('0....')
    n = 0
    a,b = 0,1
    while n<times:
        print('1....')
        yield b
        print('2....')
        a,b = b,a+b
        n+=1
    print('3....')


ge = fib(5)
print(ge)
print('*'*50)
m = 0
while m<5:
    print(next(ge))
    m+=1

4.4 send的使用

第一種和第二種,一旦生成器肯定,算法不能改變。

這裏的例子,定義了變量(temp),可使用send發送參數,發給這裏變量。

根據這個變量的值的不一樣,能夠改變算法的邏輯。

因此,這種寫法的做用:在運行過程當中,能夠改變算法

def gen():
    i = 0
    while i<1000:
        temp = yield i  
        if temp==True:
            #邏輯代碼
            print('執行A計劃')
            i+1
        else:
            #邏輯代碼
            print('執行B計劃')
            i+=2

myGenerator = gen()
ret = next(myGenerator)
print(ret)
#一、爲當前中止的代碼的左側變量賦值
#二、生成器往下走一個行,返回yield值
ret = myGenerator.send(True)
print(ret)
ret = myGenerator.send(False)
print(ret)

4.5 模擬多任務實現方式之一:模擬協程

import time

def test1():
    while True:
        print("--王者榮耀--")
        #time.sleep(2)
        yield None

def test2():
    while True:
        print("--music--")
        yield None

def main():
    t1 = test1()
    t2 = test2()
    while True:
        t1.__next__()
        t2.__next__()

main()

4.6 總結

總結

  • 生成器是這樣一個函數,它記住上一次返回時在函數體中的位置。對生成器函數的第二次(或第 n 次)調用跳轉至該函數中間,而上次調用的全部局部變量都保持不變。
  • 生成器不只「記住」了它數據狀態;生成器還「記住」了它在流控制構造(在命令式編程中,這種構造不僅是數據值)中的位置。

生成器的特色:

  1. 節約內存
  2. 迭代到下一次的調用時,所使用的參數都是第一次所保留下的,便是說,在整個全部函數調用的參數都是第一次所調用時保留的,而不是新建立的

5 迭代器

迭代是訪問集合元素的一種方式。迭代器是一個能夠記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直到全部的元素被訪問完結束。迭代器只能往前不會後退。

5.1 可迭代對象

以直接做用於 for 循環的數據類型有如下幾種:

  • 一類是集合數據類型,如 list 、 tuple 、 dict 、 set 、 str 等;
  • 一類是 generator ,包括生成器和帶 yield 的generator function。

這些能夠直接做用於 for 循環的對象統稱爲可迭代對象: Iterable 。

5.2 迭代器

isinstance(對象,Iterable)
若是結果爲True
只是表示,這些對象以使用for循環迭代遍歷,可使用next

import collections


ge = (x for x in range(10))
print(isinstance(ge,collections.Iterable))  #True
print(isinstance(ge,collections.Iterator))  #True

print(next(ge))  #0

print('************************華麗的分割線************************')

ls = [x for x in range(10)]
print(isinstance(ls,collections.Iterable))  #True
print(isinstance(ls,collections.Iterator))  #False
for i in ls:
    print(i)       #0-9的數

5.3 iter()函數

  • 生成器都是 Iterator 對象,但 list 、 dict 、 str 雖然是 Iterable ,卻不是 Iterator 。
  • 把 list 、 dict 、 str 等 Iterable 變成 Iterator 可使用 iter() 函數:
ls = [33,4,5,6,7,8]
it=iter(ls)
for i in range(len(ls)):
    print(next(it)) #33-8的數

總結

  • 凡是可做用於 for 循環的對象都是 Iterable 類型;
  • 凡是可做用於 next() 函數的對象都是 Iterator 類型
  • 集合數據類型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不過能夠經過 iter() 函數得到一個 Iterator 對象。
  • 目的是在使用集合的時候,減小佔用的內容。

6 閉包

6.1 函數引用

def test1():
    print("--- in test1 func----")

#調用函數
test1()

#此是ret引用函數
ret = test1

print(id(ret))     #18779264
print(id(test1))   #18779264,地址都同樣,說明指向同一個內存地址

#經過引用調用函數
ret()              #--- in test1 func----

6.2 閉包

  • 在函數內部再定義一個函數,而且這個內部函數用到了外部函數的局部變量
  • 那麼將這個內部函數以及用到的一些局部變量稱之爲閉包
def outer(num):
    print('outer...')
    def inner():
        print('num=%s'%num)
    return inner

ret = outer(100) #outer...
ret()            #num=100
ret()            #num=100
def line_conf(a, b):
    def line(x):
        return a*x + b
    return line


line1 = line_conf(2,3)
print(line1(10))   #23

line2 = line_conf(3,4)
print(line2(10))   #34

閉包的優缺點

  1. 閉包似優化了變量,原來須要類對象完成的工做,閉包也能夠完成
  2. 因爲閉包引用了外部函數的局部變量,則外部函數的局部變量沒有及時釋放,消耗內存

7 裝飾器

  • 裝飾器,裝飾器是閉包現象的一種體現,功能就是在運行原來功能基礎上,加上一些其它功能,好比權限的驗證,好比日誌的記錄等等。不修改原來的代碼,進行功能的擴展。

7.1 簡單的裝飾器

def outer(func):
    print('outer...')
    def inner():
        print('inner...')
        func()
    return inner


def save():
    print('save...')


ret = outer(save) #outer
ret()             #inner...   save...
def login(func):
    def inner():
        name = input('輸入用戶名:')
        pwd = input('輸入密碼:')
        if name=='laowang' and pwd=='123':
            func()
        else:
            print('趕忙去登陸。。。。。。')
    return inner


@login
def save():
    print('save...')

save()

7.2 多個裝飾器

  • 多個裝飾器,按照從內往外(從下往上)前後順序執行
  • 爲了方便記憶:能夠理解爲先寫後運行,先寫後結束
def makeBold(fn):
    print('makeBold...')
    def wrapped():
        return "--1--" + fn() + "--1--"
    return wrapped

def makeItalic(fn):
    print('makeItalic...')
    def wrapped():
        return "--2--" + fn() + "--2--"
    return wrapped

@makeBold
@makeItalic
def test():
    return "hello world-test"

print(test())
#結果
#makeItalic...
#makeBold...
#--1----2--hello world-test--2----1--

7.3 裝飾器功能

  1. 引入日誌
  2. 函數執行時間統計
  3. 執行函數前預備處理
  4. 執行函數後清理功能
  5. 權限校驗等場景
  6. 異常的處理
  7. 緩存

7.4 裝飾器示例

  1. 無參數的函數
from time import ctime, sleep

def timefun(func):
    def wrappedfunc():
        print("%s called at %s"%(func.__name__, ctime()))
        func()
    return wrappedfunc

@timefun
def foo():
    print("I am foo")

foo()  #foo called at Thu Jul 20 16:03:59 2017
       #I am foo
sleep(2)
foo()
foo = timefun(foo)
#foo先做爲參數賦值給func後,foo接收指向timefun返回的wrappedfunc
foo()
#調用foo(),即等價調用wrappedfunc()
#內部函數wrappedfunc被引用,因此外部函數的func變量(自由變量)並無釋放
#func裏保存的是原foo函數對象
  1. 被裝飾的函數有參數
def timefun(func):
    def wrappedfunc(a, b):
        print("%s called at %s"%(func.__name__, ctime()))
        print(a, b)
        func(a, b)
    return wrappedfunc

@timefun
def foo(a, b):
    print(a+b)

foo(3,5)
#foo called at Thu Jul 20 16:07:48 2017
#3 5
#8
  1. 被裝飾的函數有不定長參數
from time import ctime, sleep

def timefun(func):
    def wrappedfunc(*args, **kwargs):
        print(args)
        print(kwargs)
        print("%s called at %s"%(func.__name__, ctime()))
        func(*args,**kwargs)
    return wrappedfunc

@timefun
def foo(a, b, c,num):
    print(a+b+c)
    print(num)

foo(3,5,7,num=123)
#(3, 5, 7)
#{'num': 123}
#foo called at Thu Jul 20 16:11:06 2017
#15
#123
  1. 裝飾器中的return
from time import ctime, sleep

def timefun_arg(pre="hello"):
    def timefun(func):
        def wrappedfunc():
            print("%s called at %s %s"%(func.__name__, ctime(), pre))
            return func()
        return wrappedfunc
    return timefun

@timefun_arg("wangcai")
def foo():
    print("I am foo")

@timefun_arg("python")
def too():
    print("I am too")

foo()
#foo called at Thu Jul 20 16:23:48 2017 wangcai
#I am foo
print('************************華麗的分割線************************')
too()
#too called at Thu Jul 20 16:23:48 2017 python
#I am too

總結:
通常狀況下爲了讓裝飾器更通用,能夠有return

  1. 裝飾器帶參數,在原有裝飾器的基礎上,設置外部變量
def haha(x):
    def outer(func):
        def inner():
            if x%2==0:
                return func()+'八'
            else:
                return '八'+func()
        return inner
    return outer

@haha(1)
def laowang():
     return '老王'

print(laowang())  #八老王
  1. 類裝飾器(擴展,非重點)
    裝飾器函數實際上是這樣一個接口約束,它必須接受一個callable對象做爲參數,而後返回一個callable對象。在Python中通常callable對象都是函數,但也有例外。只要某個對象重寫了__call__()方法,那麼這個對象就是callable的。
class Test(object):
    def __init__(self, func):
        print("---初始化---")
        print("func name is %s"%func.__name__)
        self.__func = func
    def __call__(self):
        print("---裝飾器中的功能---")
        self.__func()
#說明:
#1. 當用Test來裝做裝飾器對test函數進行裝飾的時候,首先會建立Test的實例對象
#    而且會把test這個函數名當作參數傳遞到__init__方法中
#    即在__init__方法中的func變量指向了test函數體
#
#2. test函數至關於指向了用Test建立出來的實例對象
#
#3. 當在使用test()進行調用時,就至關於讓這個對象(),所以會調用這個對象的__call__方法
#
#4. 爲了可以在__call__方法中調用原來test指向的函數體,因此在__init__方法中就須要一個實例屬性來保存這個函數體的引用
#    因此纔有了self.__func = func這句代碼,從而在調用__call__方法中可以調用到test以前的函數體
@Test
def test():
    print("----test---")
test()
showpy()#若是把這句話註釋,從新運行程序,依然會看到"--初始化--"
運行結果以下:
---初始化---
func name is test
---裝飾器中的功能---
----test---

8 python是動態語言

8.1 動態語言的定義

動態編程語言是高級程序設計語言的一個類別,在計算機科學領域已被普遍應用。它是一類 在運行時能夠改變其結構的語言 :例如新的函數、對象、甚至代碼能夠被引進,已有的函數能夠被刪除或是其餘結構上的變化。動態語言目前很是具備活力。例如JavaScript即是一個動態語言,除此以外如 PHP 、 Ruby 、 Python 等也都屬於動態語言,而 C 、 C++ 等語言則不屬於動態語言。----來自維基百科

8.2 運行的過程當中給類、對象綁定(添加)屬性、方法

class mv_hero:
    def __init__(self,name,HP,MP):
        self.name = name
        self.HP = HP
        self.MP = MP
#調用,實例化
gtx = mv_hero('cjr',10,10)
print(gtx.name) #cjr
#添加一個實例屬性
gtx.XP = 100
print(gtx.XP) #100
#添加一個類屬性
mv_hero.xx = 99
#gtx.xx = 111
print(gtx.xx) #99

#定義一個類方法
@classmethod
def atteck(cls):
    cls.num = 100
#定義一個靜態方法
@staticmethod
def test_hero():
    print('--test_hero--')

#給mv_hero類綁定類方法
mv_hero.atteck = atteck
#調用剛纔綁定的類方法
mv_hero.atteck()
print(mv_hero.num)   #100

#給mv_hero類綁定靜態方法
mv_hero.test_hero = test_hero
#調用剛纔綁定的靜態方法
mv_hero.test_hero()  #--test_hero--

import types
#定義一個實例方法
def fly(self, speed):
    print("%s在移動, 速度是 %s"%(self.name, speed))
#給mv_hero中的對象綁定實例方法
gtx.fly = types.MethodType(fly, gtx)
#調用剛纔的實例方法
gtx.fly(180)  #cjr在移動, 速度是 180

9 元類

如今回到咱們的大主題上來,到底是爲何你會去使用這樣一種容易出錯且晦澀的特性?好吧,通常來講,你根本就用不上它!

'''
    使用type建立類
    

    type的第3個參數
    一、字符串 類名
    二、元組   父類
    三、字典      類屬性
'''


'''
class Test:
    pass
'''
Test = type('Test',(),{})
print(Test)


Test = type('Test',(),{'name':'老王','age':10})

print(Test.name)


class Fu:
    def fu(self):
        print('fu...')

Zi = type('Zi',(Fu,),{})
print(Zi.__mro__)


print('***************************************華麗的分割線***************************************')

def haha(self):
    print('haha...')

def __init__(self,num):
    print('self...')
    self.num = num

@classmethod
def hehe(cls):
    print('hehe...')

Test = type('Test',(),{'name':'老王','age':10,'haha':haha,'hehe':hehe,'__init__':__init__})

t = Test(110)
t.haha()

Test.hehe()

10 垃圾回收

10.1 小整數對象池

  • 整數在程序中的使用很是普遍,Python爲了優化速度,使用了小整數對象池, 避免爲整數頻繁申請和銷燬內存空間。
  • Python 對小整數的定義是 [-5, 257) 這些整數對象是提早創建好的,不會被垃圾回收。在一個 Python 的程序中,全部位於這個範圍內的整數使用的都是同一個對象.
  • 同理,單個字母也是這樣的。
  • 可是當定義2個相同的字符串時,引用計數爲0,觸發垃圾回收

10.2 大整數對象池

  • 每個大整數,均建立一個新的對象

10.3 intern機制

python建立9個」HelloWorld」對象,讓他只佔用一個」HelloWorld」所佔的內存空間,python中有這樣一個機制——intern機制,靠引用計數去維護什麼時候釋放。

字符串(含有空格),不可修改,沒開啓intern機制,不共用對象,引用計數爲0,銷燬。

總結

  • 小整數[-5,257)共用對象,常駐內存
  • 單個字符共用對象,常駐內存
  • 單個單詞,不可修改,默認開啓intern機制,共用對象,引用計數爲0,則銷燬

10.4Garbage collection(GC垃圾回收)

python採用的是引用計數機制爲主,標記-清除和分代收集兩種機制爲輔的策略

11 內建屬性

12 內建函數

  1. map():map函數會根據提供的函數對指定序列作映射
map(function, sequence[, sequence, ...]) -> list
·function:是一個函數
·sequence:是一個或多個序列,取決於function須要幾個參數
·返回值是一個列表
參數序列中的每個元素分別調用function函數
返回包含每次function函數返回值的list。
注意:先轉成list才能print
>>>def square(x) :            # 計算平方數
...     return x ** 2

>>> map(square, [1,2,3,4,5])   # 計算列表和:1+2+3+4+5
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函數
[1, 4, 9, 16, 25]
 
# 提供了兩個列表,對相同位置的列表數據進行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]
  1. range():
range(start, stop[, step]) -> list of integers
·start:計數從start開始。默認是從0開始。例如range(5)等價於range(0,5);
·stop:到stop結束,但不包括stop.例如:range(0,5) 是[0, 1, 2, 3, 4]沒有5
·step:每次跳躍的間距,默認爲1。例如:range(0,5) 等價於range(0, 5, 1)
python2中range返回列表,python3中range返回一個迭代值。若是想獲得列表,可經過list函數
  1. filter():filter函數會對指定序列執行過濾操做
filter(function or None, sequence) -> list, tuple, or string
·function:接受一個參數,返回布爾值True或False
·sequence:序列能夠是str,tuple,list
·返回值是一個列表
過濾出列表中的全部奇數:

def is_odd(n):
    return n % 2 == 1
 
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)

輸出結果 :
[1, 3, 5, 7, 9]
  1. sorted()

    sort 與 sorted 區別:
    sort 是應用在 list 上的方法,sorted 能夠對全部可迭代的對象進行排序操做。
    list 的 sort 方法返回的是對已經存在的列表進行操做,而內建函數 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操做。

sorted(iterable, key=None, reverse=False) --> new sorted list
reverse默認值爲False,升序排序
>>>a = [5,7,6,3,4,1,2]
>>> b = sorted(a)       # 保留原列表
>>> a 
[5, 7, 6, 3, 4, 1, 2]
>>> b
[1, 2, 3, 4, 5, 6, 7]
 
>>> L=[('b',2),('a',1),('c',3),('d',4)]
>>> sorted(L, cmp=lambda x,y:cmp(x[1],y[1]))   # 利用cmp函數
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
>>> sorted(L, key=lambda x:x[1])               # 利用key
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
 
 
>>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>> sorted(students, key=lambda s: s[2])            # 按年齡排序
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
 
>>> sorted(students, key=lambda s: s[2], reverse=True)       # 按降序
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
  1. reduce():reduce函數會對參數序列中元素進行累積
reduce(function, sequence[, initial]) -> value
·function:該函數有兩個參數
·sequence:序列能夠是str,tuple,list
·initial:固定初始值

reduce依次從sequence中取一個元素,
和上一次調用function的結果作參數再次調用function。 

第一次調用function時,若是提供initial參數,
會以sequence中的第一個元素和initial做爲參數調用function,
不然會以序列sequence中的前兩個元素作參數調用function。 
注意function函數不能爲None。

在Python3裏,reduce函數已經被從全局名字空間裏移除了,它如今被放置在fucntools模塊裏用的話要先引入:from functools import reduce

>>>def add(x, y) :            # 兩數相加
...     return x + y
... 
>>> reduce(add, [1,2,3,4,5])   # 計算列表和:1+2+3+4+5
15
>>> reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函數
15
def f(x,y):
    print('x=%s,y=%s'%(x,y))
    return x+y

#ret = functools.reduce(lambda x, y: x+y, ['a','b','c','d'],'o')
ret = functools.reduce(f, ['a','b','c','d'],'o')


運行結果:
x=o,y=a
x=oa,y=b
x=oab,y=c
x=oabc,y=d

13 functools

functools 是python2.5被引人的,一些工具函數放在此包裏。

知道有這麼個東西

14 模塊進階

14.1 經常使用標準庫

標準庫 說明
builtins 內建函數默認加載
sys 操做系統藉口
functooks 經常使用的工具
json 編碼和解碼JSON對象
logging 記錄日誌、調試
multiprocessing 多進程
threading 多線程
copy 拷貝
time 時間
datetime 日期和時間
calendar 日曆
hashlib 加密算法
random 生成隨機數
re 字符串正則匹配
socket 標準的BSD Sockets API
shutil 文件和目錄管理
glob 基於文件通配符搜索

更多標準庫
http://python.usyiyi.cn/translate/python_352/library/index.html

15 編碼風格

在pycharm裏,Ctrl+Alt+L自動排版,排版的時候注意看一看就記住了

16 代碼調試

pycharm
步驟:

  1. 設置斷點
  2. shift+f9 開始調試
  3. 光標就在斷點處停了。這一行沒有運行的
  4. 下一行:f8
  5. 進入方法:f7
  6. 跳到下一個斷點:alt+f9
  7. 進入方法,跳出這一步,shift+f8
相關文章
相關標籤/搜索