Python 的GIL丛肮,深拷貝和淺拷貝赡磅,私有化,多繼承宝与,閉包

Python的GIL全局解釋鎖只存在CPython解釋器焚廊,使用其他語(yǔ)言編寫(xiě)的解釋器是沒(méi)有這個(gè)問(wèn)題的
GIL面試題如下
描述Python GIL的概念,以及它對(duì)python多線程的影響习劫?
編寫(xiě)一個(gè)多線程抓取網(wǎng)頁(yè)的程序咆瘟,并闡明多線程抓取程序是否可比單線程性能有提升,并解釋原因诽里。

參考答案:
1. Python語(yǔ)言和GIL沒(méi)有半毛錢(qián)關(guān)系袒餐。僅僅是由于歷史原因在Cpython虛擬機(jī)(解釋器),難以移除GIL。
2. GIL:全局解釋器鎖灸眼。每個(gè)線程在執(zhí)行的過(guò)程都需要先獲取GIL卧檐,保證同一時(shí)刻只有一個(gè)線程可以執(zhí)行代碼
3. 線程釋放GIL鎖的情況: 在IO操作等可能會(huì)引起阻塞的system call之前,可以暫時(shí)釋放GIL幢炸,
  但在執(zhí)行完畢后泄隔,必須重新獲取GIL Python 3.x使用計(jì)時(shí)器(執(zhí)行時(shí)間達(dá)到閾值后,當(dāng)前線程釋放GIL)
  或Python 2.x宛徊,tickets計(jì)數(shù)達(dá)到100
Python使用多進(jìn)程是可以利用多核的CPU資源的佛嬉。
3. 多線程爬取比單線程性能有提升,因?yàn)橛龅絀O阻塞會(huì)自動(dòng)釋放GIL鎖

深拷貝闸天、淺拷貝

1. 淺拷貝
淺拷貝是對(duì)于一個(gè)對(duì)象的頂層拷貝
通俗的理解是:拷貝了引用暖呕,并沒(méi)有拷貝內(nèi)容

2. 深拷貝
深拷貝是對(duì)于一個(gè)對(duì)象所有層次的拷貝(遞歸)
淺拷貝對(duì)不可變類(lèi)型和可變類(lèi)型的copy不同

import copy
copy.copy() 和 copy.deepcopy() 的兩個(gè)copy方法
  對(duì)于可變類(lèi)型,會(huì)進(jìn)行淺拷貝
  對(duì)于不可變類(lèi)型苞氮,不會(huì)拷貝湾揽,僅僅是指向
  對(duì)于不可變類(lèi)型包含可變類(lèi)型,copy.copy() 淺拷貝笼吟,copy.deepcopy() 全部拷貝

如果copy.copy拷貝的是元組库物,那么它不會(huì)進(jìn)行拷貝,僅僅是指向
原因:因?yàn)樵M是不可變類(lèi)型贷帮,那么意味著數(shù)據(jù)一定不能修改戚揭,因此copy.copy的時(shí)候它會(huì)自動(dòng)判斷,
  如果是元組就是指向

如果拷貝的是元組包含列表類(lèi)型的數(shù)據(jù)撵枢,copy.copy() 進(jìn)行淺拷貝民晒,copy.deepcopy() 進(jìn)行全部拷貝
測(cè)試 深拷貝 和 淺拷貝
1. test
import copy

a = [11, 22]
b = [33, 44]
c = [a, b]
d = copy.copy(c)

print(id(c) == id(d))  # False
print(id(c[0]) == id(d[0]))  # True
copy.copy() 拷貝可變類(lèi)型,只是淺拷貝

2. test
import copy

a = (11, 22)
b = (33, 44)
c = (a, b)
d = copy.copy(c)

print(id(c) == id(d))  # True
print(id(c[0]) == id(d[0]))  # True
copy.copy() 拷貝不可變類(lèi)型锄禽,只是指向

3. test
import copy

a = [11, 22]
b = [33, 44]
c = [a, b]
d = copy.deepcopy(c)

print(id(c) == id(d))  # False
print(id(c[0]) == id(d[0]))  # False
copy.deepcopy() 拷貝可變類(lèi)型潜必,全部拷貝

4. test
import copy

a = (11, 22)
b = (33, 44)
c = (a, b)
d = copy.deepcopy(c)

print(id(c) == id(d))  # True
print(id(c[0]) == id(d[0]))  # True
copy.deepcopy() 拷貝不可變類(lèi)型,還是指向

5. test 不可變類(lèi)型包含可變類(lèi)型沃但,就全部拷貝
import copy

a = [11, 22]
b = [33, 44]
c = (a, b)
d = copy.deepcopy(c)

print(id(c) == id(d))  # False
print(id(c[0]) == id(d[0]))  # False
copy.deepcopy() 不可變類(lèi)型包含可變類(lèi)型磁滚,就全部拷貝
c = [11, 22]
d = c[:] 與 d = copy.copy(c) 一樣,屬于淺拷貝

對(duì)于字典來(lái)說(shuō)宵晚,有一點(diǎn)不同:
import copy

a = dict(name="libai", maybe=[11, 22])
b = copy.copy(a)

print(id(a) == id(b))  # False  這里的字典是不相等的
print(id(a["maybe"]) == id(b["maybe"]))  # True 鍵值相等
copy.copy() 拷貝內(nèi)部包含可變類(lèi)型


import copy

a = dict(name="libai", maybe=[11, 22])
b = copy.deepcopy(a)

print(id(a) == id(b))  # False 這里的也是不相等
print(id(a["maybe"]) == id(b["maybe"]))  # False 都拷貝了
copy.deepcopy() 對(duì)于字典恨旱,全部拷貝

一般來(lái)說(shuō),函數(shù)傳遞的都是值的引用坝疼,必要時(shí)候需要用到深拷貝

Python 的私有化

1. xx:公有變量
2. _x:?jiǎn)吻爸孟聞澗€,私有化屬性或方法,from somemodule import * 禁止導(dǎo)入谆沃,類(lèi)對(duì)象和子類(lèi)可以訪問(wèn)
3. __xx:雙前置下劃線,避免與子類(lèi)中的屬性命名沖突钝凶,無(wú)法在外部直接訪問(wèn)(名字重整所以訪問(wèn)不到)
4. __xx__:雙前后下劃線,用戶(hù)名字空間的魔法對(duì)象或?qū)傩浴@?__init__ , 不要自己發(fā)明這樣的名字
5. xx_:?jiǎn)魏笾孟聞澗€耕陷,用于避免與Python關(guān)鍵詞的沖突

總結(jié):
1. 父類(lèi)中屬性名為_(kāi)_名字的掂名,子類(lèi)不繼承,子類(lèi)不能訪問(wèn)
2. 如果在子類(lèi)中向__名字賦值哟沫,那么會(huì)在子類(lèi)中定義的一個(gè)與父類(lèi)相同名字的屬性
3. _名的變量饺蔑、函數(shù)、類(lèi)在使用from xxx import *時(shí)都不會(huì)被導(dǎo)入

導(dǎo)入模塊

1. 直接 import
2. 通過(guò)sys模塊導(dǎo)入自定義模塊的path
  先導(dǎo)入sys模塊
  然后通過(guò)sys.path.append(path) 函數(shù)來(lái)導(dǎo)入自定義模塊所在的目錄
  導(dǎo)入自定義模塊嗜诀。
import sys
sys.path.append(r"C:\Users\Pwcong\Desktop\python")
import pwcong
pwcong.hi()
3. 通過(guò)pth文件找到自定義模塊
動(dòng)態(tài)導(dǎo)入
#a 下的 test.py 文件
def test_a():
    print('this is a')

def _test_b():
    print('this is b')

(1)導(dǎo)入模塊 from xxx import *

from a.test import *

test_a()
test_b()

輸出結(jié)果:
#找不到 test_b 函數(shù)猾警,就算改成_test_b 也是一樣
NameError: name 'test_b' is not defined 
Process finished with exit code 1

(2)導(dǎo)入模塊 __import__('a.test')

module_t = __import__('a.test') #傳入字符串
print(module_t)  #定位到 test 文件的頂級(jí)目錄 a
module_t.test.test_a()
module_t.test._test_b()  #私有函數(shù)也可調(diào)用

輸出結(jié)果:
<module 'a' (namespace)>  # a 目錄
this is a
this is b

(3)導(dǎo)入模塊 importlib

import importlib

module_t = importlib.import_module('a.test')
print(module_t)  #直接定位到 test 
module_t.test_a()
module_t._test_b()

輸出結(jié)果:
<module 'a.test' from 'C:\\Users\\libai\\PycharmProjects\\begin\\a\\test.py'> #a.test
this is a
this is b
導(dǎo)入模塊時(shí)的路徑搜索
在 ipython 中輸入下面的命令
import sys
sys.path

打印結(jié)果:
['',
 'D:\\anaconda\\Scripts',
 'D:\\anaconda\\python36.zip',
 'D:\\anaconda\\DLLs',
 'D:\\anaconda\\lib',
 'D:\\anaconda',
 'D:\\anaconda\\lib\\site-packages',
 'D:\\anaconda\\lib\\site-packages\\win32',
 'D:\\anaconda\\lib\\site-packages\\win32\\lib',
 'D:\\anaconda\\lib\\site-packages\\Pythonwin',
 'D:\\anaconda\\lib\\site-packages\\IPython\\extensions',
 'C:\\Users\\libai\\.ipython']

導(dǎo)入模塊時(shí)的路徑搜索
1. 從上面列出的目錄里依次查找要導(dǎo)入的模塊文件
2. '' 表示當(dāng)前路徑
3. 列表中的路徑的先后順序代表了python解釋器在搜索模塊時(shí)的先后順序

程序執(zhí)行時(shí)添加新的模塊路徑
sys.path.append('/home/itcast/xxx')
sys.path.insert(0, '/home/itcast/xxx')  # 插入到第一個(gè)位置,可以確保先搜索這個(gè)路徑
重新導(dǎo)入模塊
模塊被導(dǎo)入后隆敢,import module不能重新導(dǎo)入模塊发皿,重新導(dǎo)入需用reload
注意:from xxxx import 變量 時(shí),要注意導(dǎo)入的是變量的值拂蝎,而不是一個(gè)指向

封裝穴墅、繼承、多態(tài) 是面向?qū)ο蟮?大特性

多繼承

super().__init__相對(duì)于類(lèi)名.__init__温自,在單繼承上用法基本無(wú)差
但在多繼承上有區(qū)別玄货,super方法能保證每個(gè)父類(lèi)的方法只會(huì)執(zhí)行一次,而使用類(lèi)名的方法會(huì)導(dǎo)致方法被執(zhí)行多次

多繼承時(shí)悼泌,使用super方法松捉,對(duì)父類(lèi)的傳參數(shù),應(yīng)該是由于python中super的算法導(dǎo)致的原因券躁,
必須把參數(shù)全部傳遞惩坑,否則會(huì)報(bào)錯(cuò)

單繼承時(shí),使用super方法也拜,則不能全部傳遞以舒,只能傳父類(lèi)方法所需的參數(shù),否則會(huì)報(bào)錯(cuò)

多繼承時(shí)慢哈,相對(duì)于使用類(lèi)名.__init__方法蔓钟,要把每個(gè)父類(lèi)全部寫(xiě)一遍, 而使用super方法,
  只需寫(xiě)一句話(huà)便執(zhí)行了全部父類(lèi)的方法卵贱,這也是為何多繼承需要全部傳參的一個(gè)原因

使用 print(Grandson.__mro__) 顯示類(lèi)的繼承順序(前提:Son1滥沫、Son2都是Parent的子類(lèi))
(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)
面試題:以下的代碼的輸出將是什么? 說(shuō)出你的答案并解釋。
class Parent(object):
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)


答案, 以上代碼的輸出是:
1 1 1
1 2 1
3 2 3

說(shuō)明:
使你困惑或是驚奇的是關(guān)于最后一行的輸出是 3 2 3 而不是 3 2 1键俱。為什么改變了 Parent.x 的值還會(huì)
  改變 Child2.x 的值兰绣,但是同時(shí) Child1.x 值卻沒(méi)有改變?

這個(gè)答案的關(guān)鍵是编振,在 Python 中缀辩,類(lèi)變量在內(nèi)部是作為字典處理的。如果一個(gè)變量的名字沒(méi)有在當(dāng)前類(lèi)
的字典中發(fā)現(xiàn),將搜索祖先類(lèi)(比如父類(lèi))直到被引用的變量名被找到(如果這個(gè)被引用的變量名既沒(méi)有
在自己所在的類(lèi)又沒(méi)有在祖先類(lèi)中找到臀玄,會(huì)引發(fā)一個(gè) AttributeError 異常 )瓢阴。

因此,在父類(lèi)中設(shè)置 x = 1 會(huì)使得類(lèi)變量 x 在引用該類(lèi)和其任何子類(lèi)中的值為 1健无。
這就是因?yàn)榈谝粋€(gè) print 語(yǔ)句的輸出是 1 1 1荣恐。

隨后,如果任何它的子類(lèi)重寫(xiě)了該值(例如累贤,我們執(zhí)行語(yǔ)句 Child1.x = 2)叠穆,然后,
該值僅僅在子類(lèi)中被改變畦浓。這就是為什么第二個(gè) print 語(yǔ)句的輸出是 1 2 1痹束。

最后,如果該值在父類(lèi)中被改變(例如讶请,我們執(zhí)行語(yǔ)句 Parent.x = 3)祷嘶,這個(gè)改變會(huì)影響到任何未重寫(xiě)
該值的子類(lèi)當(dāng)中的值(在這個(gè)示例中被影響的子類(lèi)是 Child2)。
這就是為什么第三個(gè) print 輸出是 3 2 3夺溢。

用新式類(lèi)作輸入類(lèi)型檢測(cè)论巍,get,set,del

class Type:
    def __init__(self, key):
        self.key = key
    def __get__(self, instance, owner):
        print('get 方法')
        print(instance)
        print(owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print('set 方法')
        print(instance)
        print(value)
        if not isinstance(value,str):
            print("必須傳入字符串")
            return
        instance.__dict__[self.key] = value
    def __delete__(self, instance):
        print('del 方法')
        print(instance)
        del instance.__dict__[self.key]

class earth:
    name = Type('name')
    def __init__(self, name, age):
        self.name = name
        self.age = age


e = earth('libai', 20)
print(e.__dict__)
print(e.name)
e.name = 12
print(e.__dict__)
print('----------------------------------')
del e.name
print(e.__dict__)

輸出結(jié)果:
set 方法
<__main__.earth object at 0x000002257741AEF0>
libai
{'name': 'libai', 'age': 20}
get 方法
<__main__.earth object at 0x000002257741AEF0>
<class '__main__.earth'>
libai
set 方法
<__main__.earth object at 0x000002257741AEF0>
12
必須傳入字符串
{'name': 12, 'age': 20}
----------------------------------
del 方法
<__main__.earth object at 0x000002257741AEF0>
{'age': 20}

改進(jìn)上面的程序,使得可以檢測(cè) 多種類(lèi)型

class Type:
    def __init__(self, key, except_type):
        self.key = key
        self.except_type = except_type
    def __get__(self, instance, owner):
        print('get 方法')
        print(instance)
        print(owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print('set 方法')
        print(instance)
        print(value)
        if not isinstance(value,self.except_type):
            print("必須傳入 %s " %self.except_type)
            return
        instance.__dict__[self.key] = value
    def __delete__(self, instance):
        print('del 方法')
        print(instance)
        del instance.__dict__[self.key]

class earth:
    name = Type('name', str)
    age = Type('age', int)
    def __init__(self, name, age):
        self.name = name
        self.age = age


e = earth('libai', 20)
print('---------------------------------')
e.name = 20
print('---------------------------------')

e.age = 'bbs'

輸出結(jié)果:
set 方法
<__main__.earth object at 0x000002254086D080>
libai
set 方法
<__main__.earth object at 0x000002254086D080>
20
---------------------------------
set 方法
<__main__.earth object at 0x000002254086D080>
20
必須傳入 <class 'str'> 
---------------------------------
set 方法
<__main__.earth object at 0x000002254086D080>
bbs
必須傳入 <class 'int'> 
Python 的閉包
def deco(x, y):
    def wrapper(z):
        return x+y+z
    return wrapper

d = deco(100, 200)

print(d(300))  // 600

思考:函數(shù)风响、匿名函數(shù)嘉汰、閉包、對(duì)象 當(dāng)做實(shí)參時(shí) 有什么區(qū)別状勤?
1. 匿名函數(shù)能夠完成基本的簡(jiǎn)單功能鞋怀,,持搜,傳遞是這個(gè)函數(shù)的引用 只有功能
2. 普通函數(shù)能夠完成較為復(fù)雜的功能密似,,葫盼,傳遞是這個(gè)函數(shù)的引用 只有功能
3. 閉包能夠?qū)⑤^為復(fù)雜的功能残腌,,贫导,傳遞是這個(gè)閉包中的函數(shù)以及數(shù)據(jù)抛猫,因此傳遞是功能+數(shù)據(jù)
4. 對(duì)象能夠完成最為復(fù)雜的功能,孩灯,闺金,傳遞是很多數(shù)據(jù)+很多功能,因此傳遞是功能+數(shù)據(jù)

裝飾器峰档,改成類(lèi)型檢測(cè)掖看,如果檢測(cè)到不匹配匣距,就print 和不寫(xiě)入

def deco(**kwargs): #接收參數(shù)傳入**kwargs
    def wrapper(obj): #返回的 wrapper 傳入earth
        print('========================')
        for key,value in kwargs.items(): # .items() 格式為元組
            setattr(obj, key, Type(key, value))
        return obj
    print(kwargs)
    return wrapper

#類(lèi)型傳入檢測(cè)
class Type:
    def __init__(self, key, except_type):
        self.key = key
        self.except_type = except_type
    def __get__(self, instance, owner):
        print('get 方法')
        print(instance)
        print(owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print('set 方法')
        print(instance)
        print(value)
        if not isinstance(value,self.except_type):
            print("必須傳入 %s " %self.except_type)
            return
        instance.__dict__[self.key] = value
    def __delete__(self, instance):
        print('del 方法')
        print(instance)
        del instance.__dict__[self.key]

@deco(name=str,age=int) #name 傳入類(lèi)型 str,age傳入類(lèi)型 int
class earth:
    def __init__(self, name, age):
        self.name = name
        self.age = age

e = earth('libai', '23') #觸發(fā)set方法

print('*************************************************')
print(earth.__dict__)
print(e.__dict__)

輸出結(jié)果:
{'name': <class 'str'>, 'age': <class 'int'>}
========================
set 方法
<__main__.earth object at 0x0000025C38B4E080>
libai
set 方法
<__main__.earth object at 0x0000025C38B4E080>
23
必須傳入 <class 'int'> 
*************************************************
{'__module__': '__main__', '__init__': <function earth.__init__ at 0x0000025C38B34950>, '__dict__': <attribute '__dict__' of 'earth' objects>, '__weakref__': <attribute '__weakref__' of 'earth' objects>, '__doc__': None, 'name': <__main__.Type object at 0x0000025C38B4AF98>, 'age': <__main__.Type object at 0x0000025C38B4E048>}
{'name': 'libai'}

@property 就是把裝飾的類(lèi)或者函數(shù)當(dāng)成參數(shù)傳入 property(類(lèi)) 中哎壳,執(zhí)行完后把返回值再賦給所裝飾的類(lèi),下面是自定義的 @property尚卫,與原生的@property 有類(lèi)似的功能

class Lazyproperty:
    def __init__(self, func):
        self.func = func
        print('func = ', self.func)
    def __get__(self, instance, owner):
        print('instance = ', instance)
        print('owner = ', owner)
        # 以下這句 self.func(instance) 被執(zhí)行并賦值給print打印時(shí)归榕,
        # 會(huì)執(zhí)行一遍 test 函數(shù),這也就是為什么輸出結(jié)果中會(huì)有兩個(gè) test被打印
        print('------------------>>>', self.func(instance))
        print('***************************************************')
        return self.func(instance)

class earth:
    def __init__(self):
        pass
    @Lazyproperty
    def test(self):
        print('test')
        return '你好嗎吱涉?'

e = earth()
print(e.test)

輸出結(jié)果:
func =  <function earth.test at 0x0000021C699B47B8>
instance =  <__main__.earth object at 0x0000021C699CAEB8>
owner =  <class '__main__.earth'>
test
------------------>>> 你好嗎刹泄?  # test 被打印兩次
***************************************************
test
你好嗎?

優(yōu)先級(jí)尋找十分重要啊怎爵,

class Lazyproperty:
    def __init__(self, func):
        self.func = func
    def __get__(self, instance, owner):
        print('get')
        res = self.func(instance)
        setattr(instance, self.func.__name__, res)
        return res
    # 如果存在 __set__ 方法特石,class Lazyproperty 為數(shù)據(jù)描述符,優(yōu)先級(jí)高于實(shí)例屬性鳖链,
    # 尋找屬性時(shí)會(huì)優(yōu)先尋找 數(shù)據(jù)描述符姆蘸,就會(huì)每次執(zhí)行都調(diào)用一次 get 方法
    # 現(xiàn)在不存在 __set__ 方法,class Lazyproperty 為非數(shù)據(jù)描述符芙委,優(yōu)先級(jí)低于實(shí)例屬性逞敷,
    # 尋找屬性時(shí)會(huì)優(yōu)先尋找 實(shí)例屬性,
    # 整個(gè)程序執(zhí)行過(guò)程:
        # 首先呢灌侣,@Lazyproperty 會(huì)先執(zhí)行一遍推捐,把 test 函數(shù)當(dāng)成參數(shù)傳入,
        # 實(shí)例化后再賦給test侧啼,下面牛柒,實(shí)例化 earth 類(lèi)為 e,直接傳參到
        # self.x 和 self.y 痊乾;
        # 調(diào)用 e.test 過(guò)程中皮壁,會(huì)先尋找 e 的實(shí)例屬性,實(shí)例屬性不存在 test符喝,
        # 那就去找非數(shù)據(jù)描述符闪彼, class Lazyproperty 的 get 方法被執(zhí)行,
        # instance 是類(lèi)的實(shí)例协饲,也就是 e 畏腕,self.func 就是 test,
        # owner 是 earth 類(lèi)茉稠,在 earth 類(lèi)中的 test 函數(shù)必須傳入一個(gè)參數(shù)描馅,
        # 也就是 instance ,self.func(instance) 執(zhí)行結(jié)果被存到 e.__dict__
        # 實(shí)例屬性中而线,之后 get 方法就不會(huì)執(zhí)行了铭污,因?yàn)樵趯?shí)例屬性中找得到結(jié)果
        # 可以實(shí)現(xiàn)不用每次執(zhí)行都計(jì)算一遍
    # def __set__(self, instance, value):
    #     pass

class earth:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    @Lazyproperty
    def test(self):
        return (self.x*self.y)

e = earth(10,22)
print(e.test)
print(e.test)
print(e.test)
print(e.__dict__)

輸出結(jié)果:
get
220
220
220
{'x': 10, 'y': 22, 'test': 220}

類(lèi)創(chuàng)建實(shí)例對(duì)象恋日,元類(lèi)創(chuàng)建類(lèi),python 中任何 class 定義的類(lèi)其實(shí)都是 type 類(lèi)實(shí)例化的對(duì)象嘹狞,類(lèi)也可以直接用 type 來(lái)創(chuàng)建

class Foo:
    def __init__(self):
        pass

def __init__(self):
    pass

earth = type('earth',(object,),{'__init__':__init__,'x':28})
print(earth.__dict__)
print('---------------------------------------------------------')
print(Foo)
print(Foo.__dict__)
print(type(Foo))
print(type(type(type(Foo)))) # type 又是誰(shuí)創(chuàng)建的呢岂膳? 還是 type!

輸出結(jié)果:
{'__init__': <function __init__ at 0x0000019D88944598>, 'x': 28, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'earth' objects>, '__weakref__': <attribute '__weakref__' of 'earth' objects>, '__doc__': None}
---------------------------------------------------------
<class '__main__.Foo'>
{'__module__': '__main__', '__init__': <function Foo.__init__ at 0x0000019D88944620>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
<class 'type'>
<class 'type'> # 類(lèi)的類(lèi)的類(lèi)的類(lèi)

自定義元類(lèi)

class MyType(type):
    def __init__(self, a, b, c):
        print('元類(lèi)的構(gòu)造函數(shù)執(zhí)行')
    def __call__(self, *args, **kwargs):
        obj = object .__new__(self)
        self.__init__(obj, *args, **kwargs)
        return obj
class Foo(metaclass=MyType):
    def __init__(self, name):
        self.name = name

f1 = Foo('alex')

http://www.cnblogs.com/linhaifeng/articles/6232220.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市磅网,隨后出現(xiàn)的幾起案子谈截,更是在濱河造成了極大的恐慌,老刑警劉巖涧偷,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件簸喂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡燎潮,警方通過(guò)查閱死者的電腦和手機(jī)喻鳄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)确封,“玉大人除呵,你說(shuō)我怎么就攤上這事∮绶剩” “怎么了竿奏?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)腥放。 經(jīng)常有香客問(wèn)我泛啸,道長(zhǎng),這世上最難降的妖魔是什么秃症? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任候址,我火速辦了婚禮,結(jié)果婚禮上种柑,老公的妹妹穿的比我還像新娘岗仑。我一直安慰自己,他們只是感情好聚请,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布荠雕。 她就那樣靜靜地躺著,像睡著了一般驶赏。 火紅的嫁衣襯著肌膚如雪炸卑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,482評(píng)論 1 302
  • 那天煤傍,我揣著相機(jī)與錄音盖文,去河邊找鬼。 笑死蚯姆,一個(gè)胖子當(dāng)著我的面吹牛五续,可吹牛的內(nèi)容都是我干的洒敏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼疙驾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凶伙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起它碎,我...
    開(kāi)封第一講書(shū)人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镊靴,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后链韭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡煮落,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年敞峭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝉仇。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旋讹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出轿衔,到底是詐尸還是另有隱情沉迹,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布害驹,位于F島的核電站鞭呕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宛官。R本人自食惡果不足惜葫松,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望底洗。 院中可真熱鬧腋么,春花似錦、人聲如沸亥揖。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)费变。三九已至摧扇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胡控,已是汗流浹背扳剿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昼激,地道東北人庇绽。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓锡搜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瞧掺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耕餐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

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

  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,797評(píng)論 0 38
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,331評(píng)論 0 10
  • 茉莉說(shuō)肠缔,她迷戀站臺(tái),近乎癡迷的那種哼转。我瞪大眼睛明未,說(shuō)你沒(méi)事吧!她說(shuō)她很好壹蔓,她喜歡站臺(tái)是因?yàn)樵谀莻€(gè)地方趟妥,始終有人在離開(kāi)...
    原木C閱讀 414評(píng)論 0 1
  • 今天學(xué)習(xí)了《成為作家》第86到89頁(yè),重新看待世界需要從大街上的陌生人開(kāi)始佣蓉,觀察每一個(gè)人每一個(gè)細(xì)節(jié)每一個(gè)動(dòng)作披摄。其實(shí)...
    喜水閱讀 390評(píng)論 2 3
  • 媽媽在電話(huà)里哀怨的說(shuō):“你畢業(yè)了是不是就回來(lái)這邊找工作了疚膊?我都好久沒(méi)見(jiàn)過(guò)你了∠罕辏” 我說(shuō):“媽媽呀寓盗,你怎么那么煽情,...
    林子一閱讀 274評(píng)論 1 1