生成器與反射

morra發表於2016-11-02

1. 生成器

def f():        #生成器函式
    print(11)
    yield 1

    print(22)
    yield 2

    print(33)
    yield 3

    print(44)
    yield 4

r = f()  # 這裡只獲取了一個生成器
ret = r.__next__()  #11,進入生成器函式f(),直到返回第一個yield的值
print(ret)          #1

ret = r.__next__()  #22,根據上一次的位置接著執行,直到返回第二個yield的值
print(ret)          #2

2. 反射

反射就是根據字串的形式去物件(某個模組)中操作其成員。

#index.py
inp = input("輸入模組:")
print(inp, type(inp))   #inp是字串型別

dd = __import__(inp)
inp2 = input("輸入函式:")
func = getattr(dd,inp2)

ret = func()
print(ret)


#commens.py
def f1():
   return "F1"

當模組與當前檔案不在同一目錄下的時候,需要新增fromlist=True,否則python就找不到commens模組:

dd = __import__('lib.test.commens',fromlist=True)

(1) getattr

以字串的形式,獲取模組中的某函式

import commens

target_func = getattr(commens, 'f1111', None)  # 加上None之後,如果模組中的函式不存在則直接返回None
print(target_func)

(2) hasattr

以字串的形式,判斷模組中是否存在某函式

import commens

r = hasattr(commens, 'f22')
print(r)    #False

(3) setattr

在記憶體中建立一個函式或全域性變數,不會影響檔案

import commens

r = hasattr(commens, 'ABC')
print(r)    #False

setattr(commens,'ABC',18)   在記憶體中建立一個全域性變數
#setattr(commens,'ABC',lambda a : a+1),也可以使用lambda建立函式
r = hasattr(commens, 'ABC')
print(r)    #True

(4) delattr

刪除

r = hasattr(commens, 'ABC')
print(r)    #True

delattr(commens,'ABC')

r = hasattr(commens, 'ABC')
print(r)    #False

(5) web訪問的簡單模擬

#index.py
from lib import account

url = input("輸入url:")

inp = url.split('/')[-1]    #獲取url最後面的值

if hasattr(account, inp):
    target_func = getattr(account, inp)
    r = target_func()
    print(r)
else:
    print("404")


#account.py
def login():
    return "login"
    
def logout():
    return "logout"
#簡單的web框架邏輯
url = input('請輸入"模組/函式":')

target_model,target_func = url.split('/')
m = __import__("lib."+ target_model,fromlist=True)

if hasattr(m,target_func):
    func = getattr(m,target_func)
    r = func()
    print(r)
else:
    print("404")

相關文章