類也是對象
在Python中一切都是對象凄鼻,類也不例外。所以可以對類進行以下操作。
1.可以當做參數(shù)傳遞
2.可以添加屬性
3.可以賦給變量
代碼如下:
#coding=utf-8
class Person():
pass
# 可以賦值
print(Person())
p = Person()
print(p)
# 可以當做參數(shù)傳遞
def printClass(patern):
print(patern)
printClass(Person())
# 可以添加屬性
Person.name = 'Python'
print(Person.name)
運行結果如下:
type
type其實就是元類,type的作用有兩個梅肤,第一是查看對象的類型(也可以理解為這個對象是由什么創(chuàng)建創(chuàng)建出來的),第二是可以創(chuàng)建類
代碼如下:
#coding=utf-8
class Person():
pass
print(type(Person))
print(type(type(Person)))
運行結果如下:
所以我們可以知道所有的類都是由type創(chuàng)建出來的邑茄,如果print(type(type))姨蝴,最終顯示的還是type(這里應該是采用了一個遞歸的方式)
使用type創(chuàng)建類
代碼如下:
#coding=utf-8
Test1Class = type('Test1',(),{})
test1 = Test1Class()
print(test1)
Test2Class = type('Test2',(Test1Class,),{'num':100})
test2 = Test2Class()
print(test2)
print(test2.num)
def __init__(self,age):
self.age = age
def instancemethod(self,name):
print('實例方法')
print(name)
print(self.age)
@classmethod
def classmethod(cls):
print('類方法')
cls.numtest3 = 300
@staticmethod
def staticmethod():
print('hello world')
#print(numtest3)
Test3Class = type('Test3',(Test2Class,),{'__init__':__init__,'instance':instancemethod,'class3':classmethod,'static':staticmethod,'numtest3':200})
test3 = Test3Class(18)
print(test3)
print(test3.instance('xiaohua'))
print(test3.numtest3)
print(test3.class3())
print(test3.static())
print(test3.num)
print(test3.numtest3)
運行結果如下:
metaclass
class中的變量__metaclass__
可以來決定類是由誰來創(chuàng)建
代碼如下:
#coding=utf-8
class UpperAttrMetaClass(type):
#__new__方法默認需要傳cls參數(shù)、后面三個參數(shù)依次代表:類名肺缕,類的集成似扔,類的屬性。默認由系統(tǒng)傳遞
def __new__(cls,future_class_name,future_class_parents,future_class_attr):
# 取出future_class_attr中屬性名以__開頭的搓谆,并保存在attrs這個元組中
attrs = ((name,value) for name,value in future_class_attr.items() if not name.startswith('__'))
# 將attrs元組再解開然后將其中name改為大寫炒辉,改成字典保存到uppercase_attrs中
uppercase_attrs = dict((name.upper(),value) for name,value in attrs)
# 1.通過type來做類對象的創(chuàng)建
# return type(future_class_name,future_class_parents,uppercase_attrs)
# 2.通過復用type.__new__的方法來創(chuàng)建類對象
# return type.__new__(cls,future_class_name,future_class_parents,future_class_attr)
# 3.通過super方法創(chuàng)建類對象
return super(UpperAttrMetaClass,cls).__new__(cls,future_class_name,future_class_parents,future_class_attr)
# python2用法,python3也能用
class Foo(object):
__metaclass__ = UpperAttrMetaClass
bar = 'bip'
# python3用法
# class Foo(object,metaclass = UpperAttrMetaClass):
# bar = 'bip'
# hasattr用來檢測類中是否有某屬性
print(hasattr(Foo,'bar'))
print(hasattr(Foo,'BAR'))
Python做了如下的操作:
- Foo中有metaclass這個屬性嗎泉手?如果是黔寇,Python會通過metaclass創(chuàng)建一個名字為Foo的類(對象)
- 如果Python沒有找到metaclass,它會繼續(xù)在Bar(父類)中尋找metaclass屬性斩萌,并嘗試做和前面同樣的操作缝裤。
- 如果Python在任何父類中都找不到metaclass,它就會在模塊層次中去尋找metaclass颊郎,并嘗試做同樣的操作憋飞。
- 如果還是找不到metaclass,Python就會用內(nèi)置的type來創(chuàng)建這個類對象。