1. 程式人生 > >python語言是動態語言、給類新增屬性、方法、靜態方法和類方法、__slots__()、python中的生成器、yield的用法

python語言是動態語言、給類新增屬性、方法、靜態方法和類方法、__slots__()、python中的生成器、yield的用法

程式在查詢變數的定義時遵循LEGB規則

LEGB規則:

locals-->enclosing function-->globals-->builtins
locals當前所在名稱空間的變數
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