python語言是動態語言、給類新增屬性、方法、靜態方法和類方法、__slots__()、python中的生成器、yield的用法
阿新 • • 發佈:2019-02-13
程式在查詢變數的定義時遵循LEGB規則
LEGB規則:
locals-->enclosing function-->globals-->builtinslocals當前所在名稱空間的變數
enclosing外部巢狀函式的名稱空間(閉包中常見)
global全域性變數,函式定義所在模組的名稱空間
builtins系統自帶的,比如;eval,sum,id
object類是基類
python是動態語言,比如一個類,可以在執行過程中隨時新增屬性,但是c中必須實現定義好 # #c是靜態語言:執行之前先編譯 #object是python中最頂層的基類 class Person(object): def __init__(self,name,age): self.name=name self.age=age def eat(self): print("can eat") def run(self): print("can run") p1=Person("wangming",10) p1.eat() p1.home="jia" print(p1.home) #python是動態的,所以這裡可以新增屬性 #但是不可以以下面方式新增方法 #p1.run=run #p1.run()#error 雖然p1物件run屬性已經指向了類外面定義的函式,在新定義的函式中, #並沒有把p1當作引數,導致 在呼叫中,出現缺少引數的提示 #新增一個物件的例項方法的正確方式 import types p1.run=types.MethodType(run,p1)#(function,instance),將一個函式繫結到物件上去 p1.run()# can run Run=types.MethodType(run,p1) Run()# can run 後面實現繫結,將P1作為引數傳遞給run函式,self #返回值是p1.run()的引用
靜態方法和類方法可以直接實現新增
#靜態方法沒有引數,可以直接賦值 @staticmethod def test(): print("this is a staticmethod ") Person.test=test Person.test()#this is a staticmethod @classmethod def printClass(cls): print("this is class methond") Person.printClass=printClass#相當於將這個方法賦值給類屬性 Person.printClass()#this is class method #給類新增屬性,直接新增,但是不能直接賦值的方式給一個例項物件賦值,需要用到types.MethodType() #這樣可以實現在程式沒有發生大改變的前提下,實現修改 # #__slots__()用來限制該class能新增的屬性 class Student(object): __slots__=("name","age")#限制屬性,包含屬性 st1=Student() st1.name="xiao" st1.age=32 #st1.add="d"#這句話是錯誤的,不允許新增限制之外的屬性,不過這個只對當前例項其作用,對繼承的子類不起作用 #
生成器
a=(x for x in range(10))#這是一個生成器,可以用next()進行取值 a=100 b=200 a,b=b,a #print(a,b) #200,100 # #函式中有yeild時,不能當成普通的函式,而是生成器 #生成器並不是一次開闢很多的空間,而是每次執行一次 # def creatNum(): a,b=0,1 for i in range(10): yield b #這個是每次的返回值 a,b=b,a+b #建立 一個生成器物件 a=creatNum() #可以使用next的方式列印返回值 #函式執行到yield,系統暫停,返回函式值 ret=a.__next__() print(ret) print(next(a)) print("----------") ''' for num in a:#上面的生成器可以用next()獲取下一個返回值,但是會有個條件來確定結束,這裡有for迴圈迭代 print(num)#打印出來斐波那契數列 for nu in creatNum(): print(nu) ''' ''' 1 1 ---------- 2 3 5 8 13 21 34 55 1 1 2 3 5 8 13 21 34 55 '''
yield的用法
def Generator():
i=0
while i<5:
temp=yield i
print(temp)#temp相當於是yeild i 的整體賦給temp,如果沒有值傳遞,為空
i+=1
t=Generator()
#print(t.send("這裡不能剛開始就傳值"))#系統還沒執行到這裡
#1 第一次先呼叫t.__next__(),再呼叫t.send("xxx")
#2 或者t.send(None)
#如果程式沒有給temp賦值,則temp將保留上一次的值
print(t.__next__())#0
print(t.__next__())#None 1
print(t.__next__())#None 2
print(t.send("hello"))#hello 3