Python核心編程

  1. 模塊循環導入問題
  2. 深拷貝和淺拷貝
  3. 位運算
  4. 獲取私有屬性的值
  5. property的使用
  6. 迭代器
  7. 閉包
  8. 裝飾器
  9. python動態添加屬性以及方法
  10. 生成器
 
 

1.模塊循環導入問題
#vi a.py
from b import b
def a():
    print('-----a-----')
    b()
a()
#vi b.py
from a import a
def b():
    print('-----b-----')
def c():
    print('------c-----')
    a()
c()
#python3 a.py的結果是:ImportError:cannot import name 'a'
解決辦法:不要互相調用,另外寫個 主模塊去調它們(子模塊)
 

2.深拷貝與淺拷貝
#淺拷貝
a = [11,22,33]
b = a
id(a) == id(b)   #True
 
#深拷貝
a = [11,22,33]
import copy
c = copy.deepcopy(a)
id(a) == id(b) #False
 
#copy與deepcopy的區別
copy只拷貝第一層引用;deepcopy是遞歸拷貝全部引用
當copy遇到元組時,會進行淺拷貝(只指向)
 

3.位運算
& 按位與
| 按位或
^ 按位異或
~ 按位取反
<< 按位左移
>> 按位右移
用途:直接操做二進制,省內存,效率高
按位移:
8>>1   4
8<<1   16
按位與:
全1才1不然0:只有對應的兩個二進制均爲1時,結果位才爲1,不然爲0
按位或:
有1就1 只要對應的二個二進位有一個爲1時,結果位就爲1,不然爲0
按位異或:
不一樣爲1 只要對應的二進位相異(不相同)時,結果爲1,不然爲0
取反:
~9 = -10
 

4.獲取私有屬性的值:
class Test(object):
    def __init__(self):
        self.__num = 100
    def setNum(self, newNum):
        self.__num = newNum #修改私有屬性的值
    def getNum(self):
        return self.__num #返回私有屬性的值
 
t = Test()
#print('t.__num')
#t.__num = 200
#print(t.__num)
print(t.getNum())
t.setNum(39)
print(t.getNum())
#私有化的本質是把私有屬性給更名了。如_類名__num
 

5.property的使用:
class Test(object):
    def __init__(self):
        self.__num = 100
    def setNum(self, newNum):
        self.__num = newNum #修改私有屬性的值
    def getNum(self):
        return self.__num #返回私有屬性的值
    num = property(getNum, setNum)
t = Test()
t.num = 200 #至關於t.setNum(9)
print(t.num)
注意點:
t.num 究竟是調用getNum()仍是setNum(),要根據實際的場景來判斷;
若是是給t.num賦值,那麼必定調用setNum();
若是是獲取t.num的值,那麼就必定調用getNum();
property的做用:至關於把方法進行了封裝,開發者在對屬性設置數據的時候更方便了
#使用裝飾器
class Test(object):
    def __init__(self):
        self.__num = 100
     @property
    def num(self):
        return self.__num
    @num.setter
    def num(self, newNum):
        self.__num = newNum
 
t = Test()
t.num = 200
print(t.num)
 

6.迭代器:
判斷是否爲Itarable類型
from collections import Iterable
a = isinstance('abv', Iterable)
print(a)
#判斷是否爲Iterator類型
from collections import Iterator
a = isinstance('ac', Iterator)
print(a)
使用iter()函數把Iterable變成Iterator
a = isinstance(iter('abc'), Iterator)
print(a)
 

7.閉包:
#函數裏面套用函數,裏面的函數用到了外面函數的參數,就叫作閉包
def test(number):
    def test2(number2):
        print('-----%s-----'%number2)
        return number+number2
    return test2 #返回函數的地址
 
ret = test(100) #ret已經記住了外部的參數
print(ret(20))
#一個閉包的實際例子
def line_conf(a, b):
    def line(x):
        return a*x + b
    return line
 
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5))
print(line2(5))
#函數的最終形式(y=x+!)(y=4x+5)
#1.閉包優化了變量,原來須要類對象完成的工做,閉包也能夠完成
#2.因爲閉包引用了外部函數的局部變量,則外部函數的局部變量沒有及時釋放,消耗內存
#初始設計
def function(a,b,x):
    print(a*x+b)
 
function(1,1,0)
 

8.裝飾器:
#裝飾器第一個版本
def base(func):
    def inner():
       print('-----裝飾器-----')
       func()
    return inner
 
def a():
    print('-----a------')
 
def b():
    print('-----b------')
 
innerFunc = base(b)
innerFunc()
裝飾器的第二個版本
def base(func):
    def inner():
       print('-----正在驗證權限-----')
       if False:
           func()
       else:
            print('沒有權限')
    return inner
@base
def a():
    print('-----a------')
@base
def b():
    print('-----b------')
 
b()
#裝飾器的執行順序,快遞(裝的時候是從裏往外裝,拆的時候從外往裏拆)
#coding:utf-8
def w1(func):
    print('-----正在裝飾1-----')
    def inner():
        print('-----正在驗證權限1-----')
        func()
    return inner
 
def w2(func):
    print('-----正在裝飾2-----')
    def inner():
        print('-----正在驗證權限2-----')
        func()
    return inner
 
@w1
@w2
def f1():
    print('-----f1-----')
#有參數
def func(functionName):
    print('-----func-----1---')
    def func_in(a, b): #若是a,b沒有定義,那麼會致使下面的調用失敗
        print('----func_in----1----')
        functionName(a, b)   #要把a, b看成實參進行傳遞
    print('----func----2----')
    return func_in
 
@func
def test(a, b):
    print('-----test-a=%d, b=%d-----'%(a, b))
 
test(11,22)
#不肯定參數
def func(functionName):
    print('-----func-----1---')
    def func_in(*args, **kwargs): #若是a,b沒有定義,那麼會致使下面的調用失敗
        print('----func_in----1----')
        functionName(*args, **kwargs)   #要把a, b看成實參進行傳遞
    print('----func----2----')
    return func_in
 
@func
def test(a, b, c):
    print('-----test-a=%d, b=%d-----'%(a, b, c))
 
@func
def test2(a, b, c, d):
    print('-----test-a=%d, b=%d, c=%d, d=%d---'%(a, b, c, d))
test(11,22,33)
test2(22,33,44,55)
#裝飾器對對帶有返回值的函數進行裝飾
#解ret爲None的bug
def func(functionName):
    print('-----func-----1---')
    def func_in():
        print('----func_in----1----')
        functionName()
    print('----func----2----')
    return func_in
 
@func
def test():
    print('-----tes-----')
    return 'haha'
ret = test()
print('test return value is %s'%ret)
#由於test()指向了func_in(),而func_in由調用了test(),而return的返回值卻沒有變量來接收,所以只須要找一個變量來接收functionName()的返回值就行了
#通用裝飾器
def func(functionName):
    def func_in(*args, **kwargs):
        ret = functionName(*args, **kwargs)
        return ret
    return func_in
 
@func
def test():
    print('-----test1-----')
    return 'haha'
 
@func
def test2():
    print('-----test2-----')
@func
def test3(a):
    print('----test3----a=%d--'%a)
 
ret = test()
print('test return value is %s'%ret)
a = test2()
print('test2 return value is %s'%a)
test3(11)
#帶有參數的裝飾器
def func_arg(arg):
    def func(functionName):
        def func_in():
            print('-----記錄日誌--arg=%s---'%arg)
            if arg == 'heihei':
                functionName()
                 functionName()
                        else:
                              functionName()
        return func_in
    return func
#1.先執行func_arg('heihei')函數,這個函數return的結果是func這個函數的引用
#2.@func
#3.使用@func對test進行裝飾
#帶有參數的裝飾器,可以起到在運行時,有不一樣的功能
@func_arg('heihei')
def test():
    print('-----test-----')
 
test()
 

9.動態添加屬性和方法
做用域:
什麼是命名空間?
名字起做用的範圍
globals
locals
LEGB規則:
找一個變量,先找局部,再找有沒有閉包,再找全局變量,再找內鍵
#爲類動態添加屬性
class mate(object):
    def __init__(self, Newname, Newage):
        self.name = Newname
        self.age = Newage
laowang = mate('老王', 18)
爲變量添加單一屬性
laowang.addr = '北京'
print(laowang.addr)
#爲類添加屬性
mate.addr = '中國'
print(laowang.addr)
#爲類動態添加方法
import types
class mate(object):
    def __init__(self, Newname, Newage):
        self.name = Newname
        self.age = Newage
    def eat(self):
        print('----eat----')
def run(self):
    print('-----run-----')
wang = mate('老王', 18)
wang.run = types.MethodType(run, wang)
wang.run()
#靜態方法添加
@staticmethod
def test():
    print('-----static method---')
p.test = test
p.test()
__slots__方法
使用__slots__來限制class實例能添加的屬性,可是僅能對當期的類添加限制,對繼承的子類沒有限制
__slots__ = [‘name’, ‘age’]
 

10.生成器:
第一種生成器:把列表生成式的[]變爲()
a = [x*2 for x in range(10)]
a = (x*2 for x in range(10))
print(a)
next(a)
建立生成式方法二
def creatNum():
    print('-----start-----')
    a, b = 0, 1
    for i in range(5):
        print('-----1-----')
        yield b
        print('-----2-----')
        a, b = b, a+b
    print('-----stop-----')
a = creatNum()
for num in a:
    print(num)
#send的使用
def test():
    i = 0
    while i <5:
        temp = yield i
        print(temp)
        i += 1
 
t = test()
t.__next__()
t.send('haha')
第一次調用send的解決辦法:
1.先用next,在用send
2.send(None),再使用send 
#多任務(協程)
def test1():
    while True:
        print('-----1-----')
        yield None
def test2():
    while True:
        print('-----2-----')
        yield None
t1 = test1()
t2 = test2()
while True:
    t1.__next__()
    t2.__next__()
相關文章
相關標籤/搜索