為ip池做準(zhǔn)備之 ---- __metaclass__以及eval的使用

制作ip池的時候,可能需要不定時新代理池獲取的網(wǎng)站,通常的做法是每次添加一個新的網(wǎng)站,就改一下獲取函數(shù),這樣更改添加方法很容易出錯.我們可以設(shè)想另外一種模式,當(dāng)我們要添加新的獲取網(wǎng)站的時候,我們只要添加對應(yīng)的函數(shù)就可以了,而不需要更改其他代碼,這樣會方便很多,這里我們借助元類來實(shí)現(xiàn).


__metaclass__ 的一些理解

以下是我個人理解:

  • python中,一切皆對象,元類也是一個對象
  • 元類是可以創(chuàng)造類對象的一種類
  • type除了顯示對象類型以外,還可以作為關(guān)鍵字去創(chuàng)建類

參考別人的資料得到的信息:

  • 類也是對象,當(dāng)使用關(guān)鍵字class的時候python解釋器就會自動的取創(chuàng)建一個對象,這個對象自身擁有創(chuàng)建對象(類實(shí)例,也就是我們說的類實(shí)例化出來的對象)的能力,它的本質(zhì)仍然是一個對象,于是你可以對它進(jìn)行如下操作:

    1. 你可以把它復(fù)制給一個變量
    2. 你可以copy它
    3. 你可以為它增加屬性
    4. 你可以將他作為參數(shù)進(jìn)行傳遞
  • 可以動態(tài)的在方法中創(chuàng)建類,但是仍然需要你自己編寫整個類的方法和屬性,如下列子:

def choose_class(name):
    if name == 'foo':
        class Foo(object):  # 這里就是動態(tài)的根據(jù)條件來創(chuàng)建類但是關(guān)于它的方法仍然需要自己填寫完整才能繼續(xù)
            pass
        return Foo     # 返回的是類,不是類的實(shí)例
    else:
        class Bar(object):
            pass
        return Bar

除了手動創(chuàng)建類以外typey可以可以創(chuàng)建類的,格式如下:

type(類名,父類的元祖(在有繼承的情況下,可以為空),包含屬性的字典(名稱和值))

比如我們要創(chuàng)建一個名為TestFunc(object)的類,它有一個屬性叫做name 值是 TestFunc, 那么我們可以按照下面的方式創(chuàng)建:

type(TestFunc,(object),{'name':'TestFunc'})

這樣我們就使用表達(dá)式創(chuàng)建了一個類,這個類和上面的模式使用class創(chuàng)建的類是沒有區(qū)別的.在這里發(fā)現(xiàn)可以批量性的根據(jù)自己的需要來創(chuàng)建類了.

__metaclass__屬性

這是一個類屬性,當(dāng)你用這個屬性創(chuàng)建類的時候,它就會用元類來創(chuàng)建類.

class TestFunc(AClass):
    __metaclass__=someting  

如果你這么做了桦踊,Python就會用元類來創(chuàng)建類Foo伶跷。這里面可以這樣理解枪芒。首先寫下class Foo(object),但是類對象Foo還沒有在內(nèi)存中創(chuàng)建猪狈。Python會在類的定義中尋找__metaclass__屬性抛蚁,如果找到了陈醒,Python就會用它來創(chuàng)建類Foo,如果沒有找到瞧甩,就會用內(nèi)建的type來創(chuàng)建這個類钉跷。把下面這段話反復(fù)讀幾次。當(dāng)你寫如下代碼時:

class TestFunc(Aclass):
    pass

Python做了如下的操作:

Foo中有__metaclass__這個屬性嗎肚逸?如果是爷辙,Python會在內(nèi)存中通過__metaclass__創(chuàng)建一個名字為Foo的類對象(我說的是類對象,請緊跟我的思路)朦促。如果Python沒有找到__metaclass__膝晾,它會繼續(xù)在Bar(父類)中尋找__metaclass__屬性,并嘗試做和前面同樣的操作务冕。如果Python在任何父類中都找不到__metaclass__血当,它就會在模塊層次中去尋找__metaclass__,并嘗試做同樣的操作禀忆。如果還是找不到__metaclass__,Python就會用內(nèi)置的type來創(chuàng)建這個類對象臊旭。

你可以在metaclass中放置些什么代碼呢?答案就是:可以創(chuàng)建一個類的東西箩退。那么什么可以用來創(chuàng)建一個類呢离熏?type,或者任何使用到type或者子類化type的都可以戴涝。

下面就回歸到了我們開篇說的問題如何子在不修改類已經(jīng)存在的方法的基礎(chǔ)上擴(kuò)展我們的類,答案是 -- 自定義元類

我們獲取類中所有以newfunc開頭的函數(shù)

class NewMetaclass(type):
    def __new__(cls, name, bases, attrs):
        count = 0
        attrs['__NewFunc__'] = []
        for k, v in attrs.items():
            if 'newfunc' in k:
                attrs['__NewFunc__'].append(k)
                count += 1
        attrs['__NewFuncCount__'] = count
        return type.__new__(cls, name, bases, attrs)


class NewFunc(object, metaclass=NewMetaclass):
    def newfunc_a(self):
        return 'a1'

    def new_a(self):
        return 'a2'

    def newfunc_b(self):
        return 'b1'

    def new_b(self):
        return 'b2'


test = NewFunc
count = test.__NewFuncCount__
content = test.__NewFunc__
print(count, content)

'''
運(yùn)行結(jié)果如下:
2 ['newfunc_a', 'newfunc_b']
'''

這里我們解釋下幾個參數(shù),這里對應(yīng)著我們上面說的使用type創(chuàng)建類的參數(shù):

type(類名,父類的元祖(在有繼承的情況下需要寫出來,其他可以為空),包含屬性的字典(名稱和值))

參數(shù) 含義
cls 類的實(shí)例對象
name 類的名字
bases 類所有繼承的類
attrs 包含屬性的字典

我們?yōu)槭裁匆褂迷?引用Tim Peters的一句話:
“元類就是深度的魔法撤奸,99%的用戶應(yīng)該根本不必為此操心。如果你想搞清楚究竟是否需要用到元類喊括,那么你就不需要它胧瓜。那些實(shí)際用到元類的人都非常清楚地知道他們需要做什么,而且根本不需要解釋為什么要用元類郑什「” —— Python界的領(lǐng)袖 Tim Peters

其實(shí)我們使用元類更多的就是為了創(chuàng)建API,讓功能更加方便
參考文章: 深度理解python中的元類


eval() 函數(shù)的使用

eval()官方文檔里面給出來的功能解釋是:將字符串string對象轉(zhuǎn)化為有效的表達(dá)式參與求值運(yùn)算返回計(jì)算結(jié)果

語法上:eval(expression,globals=None, locals=None)
返回的是計(jì)算結(jié)果

參數(shù)的含義:

  • expression是一個參與計(jì)算的python表達(dá)式
  • globals是可選的參數(shù)蘑拯,如果設(shè)置屬性不為None的話钝满,就必須是dictionary對象了
  • locals也是一個可選的對象,如果設(shè)置屬性不為None的話申窘,可以是任何map對象了

python是用命名空間來記錄變量的軌跡的弯蚜,命名空間是一個dictionary,鍵是變量名剃法,值是變量值碎捺。

當(dāng)一行代碼要使用變量 x 的值時,Python 會到所有可用的名字空間去查找變量,按照如下順序:

1)局部名字空間 - 特指當(dāng)前函數(shù)或類的方法收厨。如果函數(shù)定義了一個局部變量 x, 或一個參數(shù) x晋柱,Python 將使用它,然后停止搜索诵叁。

2)全局名字空間 - 特指當(dāng)前的模塊雁竞。如果模塊定義了一個名為 x 的變量,函數(shù)或類拧额,Python 將使用它然后停止搜索碑诉。

3)內(nèi)置名字空間 - 對每個模塊都是全局的。作為最后的嘗試侥锦,Python 將假設(shè) x 是內(nèi)置函數(shù)或變量联贩。

python的全局名字空間存儲在一個叫g(shù)lobals()的dict對象中;局部名字空間存儲在一個叫l(wèi)ocals()的dict對象中捎拯。我們可以用print (locals())來查看該函數(shù)體內(nèi)的所有變量名和變量值泪幌。

也就是說我們給它傳入一個字符串,它會取執(zhí)行這個字符串所代表的函數(shù)

demo:

def change():
    print('this is change func')
funcname = '{}()'.format('change')
print(funcname)
eval(funcname)
'''
結(jié)果如下:
change()
this is change func
'''

當(dāng)然這個函數(shù)使用起來也有很大的風(fēng)險,這里不再詳細(xì)說明給幾個網(wǎng)址大家可以研究下:

Python eval 函數(shù)妙用

Python之eval()函數(shù)危險性淺析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市署照,隨后出現(xiàn)的幾起案子祸泪,更是在濱河造成了極大的恐慌,老刑警劉巖建芙,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件没隘,死亡現(xiàn)場離奇詭異,居然都是意外死亡禁荸,警方通過查閱死者的電腦和手機(jī)右蒲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赶熟,“玉大人瑰妄,你說我怎么就攤上這事∮匙” “怎么了间坐?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長邑退。 經(jīng)常有香客問我竹宋,道長,這世上最難降的妖魔是什么地技? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任蜈七,我火速辦了婚禮,結(jié)果婚禮上莫矗,老公的妹妹穿的比我還像新娘飒硅。我一直安慰自己砂缩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布狡相。 她就那樣靜靜地躺著梯轻,像睡著了一般食磕。 火紅的嫁衣襯著肌膚如雪尽棕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天彬伦,我揣著相機(jī)與錄音滔悉,去河邊找鬼。 笑死单绑,一個胖子當(dāng)著我的面吹牛回官,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播搂橙,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼歉提,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了区转?” 一聲冷哼從身側(cè)響起苔巨,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎废离,沒想到半個月后侄泽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜻韭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年悼尾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肖方。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡闺魏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出俯画,到底是詐尸還是另有隱情舷胜,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布活翩,位于F島的核電站烹骨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏材泄。R本人自食惡果不足惜沮焕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拉宗。 院中可真熱鬧峦树,春花似錦辣辫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谷遂,卻和暖如春葬馋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肾扰。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工畴嘶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人集晚。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓窗悯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偷拔。 傳聞我的和親對象是個殘疾皇子蒋院,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 包(lib)、模塊(module) 在Python中莲绰,存在包和模塊兩個常見概念欺旧。 模塊:編寫Python代碼的py...
    清清子衿木子水心閱讀 3,808評論 0 27
  • 1.元類 1.1.1類也是對象 在大多數(shù)編程語言中,類就是一組用來描述如何生成一個對象的代碼段钉蒲。在Python中這...
    TENG書閱讀 1,275評論 0 3
  • 大連的六月是櫻桃的季節(jié)顷啼,櫻桃的個頭大小不一踏枣,種類也是復(fù)雜繁多。各種顏色的櫻桃钙蒙,酸甜可口茵瀑、老少皆宜、人人喜愛躬厌。國匯財...
    ce3476ab8405閱讀 209評論 0 0
  • #下店六年級上課記錄 2017/5/23# 繪本《The Princess Twins and the Tea P...
    螢火蟲ABC閱讀 542評論 0 0
  • 人马昨,即使活到八九十歲,有母親便可以多少還有點(diǎn)孩子氣扛施。失去了慈母便像花插在瓶子里鸿捧,雖然還有色有香,卻失去了根疙渣。(老舍...
    卡爾西法的麥克風(fēng)閱讀 368評論 0 0