靜態方法:
通過 @staticmethod 裝飾器即可把其裝飾的方法變為一個靜態方法。普通的方法,可以在實例化后直接調用,并且在方法里可以通過self.調用實例變量或類變量,但靜態方法是不可以訪問實例變量或類變量的,一個不能訪問實例變量和類變量的方法,其實相當于跟類本身已經沒什么關系了,它與類唯一的關聯就是需要通過類名來調用這個方法
示例:
class Dog(object):def __init__(self, name):self.name = name@staticmethoddef eat_static(food): # 不能傳入 self 否則會報錯print(' is eating %s' % food)def eat(self, food):print('%s is eating %s' % (self.name, food))d = Dog('A dog') d.eat_static('bone') # 調用靜態方法 d.eat('bone')
輸出結果:
is eating bone
A dog is eating bone
?
類方法:
類方法通過@classmethod裝飾器實現,類方法和普通方法的區別是, 類方法只能訪問類變量,不能訪問實例變量
示例:
class Dog(object):name = 'Dog' # 類變量def __init__(self, name):self.name = name@classmethoddef eat_class(cls, food): # 不能傳入 self 否則會報錯print('%s is eating %s' % (cls.name, food))def eat(self, food):print('%s is eating %s' % (self.name, food))d = Dog('A dog') d.eat_class('bone') # 調用類方法 d.eat('bone')
輸出結果:
Dog is eating bone
A dog is eating bone
?
?
屬性方法:
屬性方法的作用就是通過 @property 把一個方法變成一個靜態屬性
簡單使用示例:
class Dog(object):def __init__(self, name):self.name = name@propertydef eat(self):print("%s is eating" % self.name)d = Dog("A dog") d.eat # 調用屬性(無法直接傳參數),加括號會報錯
輸出結果:
A dog is eating
?
給屬性方法賦值
示例:
class Dog(object):def __init__(self, name):self.name = name@propertydef eat(self):print("%s is eating" % self.name)@eat.setterdef eat(self, food): # 當給屬性方法賦值時,調用這個方法print('The food is %s' % food)d = Dog("A dog") d.eat d.eat = 'bone'
輸出結果:
A dog is eating
The food is bone
?
如果希望屬性方法有參數,需要將參數存為類變量
示例:
class Dog(object):def __init__(self, name):self.name = nameself.__food = None@propertydef eat(self):print("%s is eating %s" % (self.name, self.__food))@eat.setterdef eat(self, food):print('The food is %s' % food)self.__food = foodd = Dog("A dog") d.eat d.eat = 'bone' d.eat
輸出結果:
A dog is eating None
The food is bone
A dog is eating bone
?
刪除屬性方法只需在上面函數的基礎上再寫一個:
@eat.deleterdef eat(self):del self.__food
之后再調用 self.__food屬性時就會報錯,已經找不到了。
?
類的特殊成員方法:
1.__doc__:表示類的描述信息
class Dog(object):'''這個類是用來描述狗這個對象的'''def __init__(self):passprint(Dog.__doc__)
輸出結果:
這個類是用來描述狗這個對象的
?
2.__module__、 __class__
???????? __module__ 表示當前操作的對象在那個模塊
??? __class__???? 表示當前操作的對象的類是什么
lib\aa.py:
class C(object):def __init__(self, name):self.name = name
index.py:
from lib.aa import Cobj = C('name') print(obj.__module__) print(obj.__class__)
輸出結果:
lib.aa
<class ’lib.aa.C’>
?
3.__init__:構造方法
4.__del__:析構函數
5.__call__:對象后面加括號,觸發執行
注:構造方法的執行是由創建對象觸發的,即:對象 = 類名() ;而對于 __call__ 方法的執行是由對象后加括號觸發的,即:對象() 或者 類()()
class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print('__call__')obj = Foo() # 執行 __init__ obj() # 執行 __call__ Foo()()
輸出結果:
__call__
__call__
?
6__dict__
通過類調用:查看類里的所有屬性(不包括實例里的)
通過實例調用:查看實例里的所有屬性(不包括類里的)
class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print('__call__')obj = Foo() print(Foo.__dict__) print(obj.__dict__)
輸出結果:
{'__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__module__': '__main__', '__init__': <function Foo.__init__ at 0x000001CED095D378>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__doc__': None, '__call__': <function Foo.__call__ at 0x000001CED3A9B510>}
{}
?
7.__str__:如果一個類中定義了__str__方法,那么在打印 對象 時,默認輸出該方法的返回值
不使用__str__時:
class Foo(object):def __init__(self, name):self.name = nameobj = Foo('A obj') print(obj)
輸出結果:
<__main__.Foo object at 0x0000024051A5F0F0>
?
如果加上__str__:
class Foo(object):def __init__(self, name):self.name = namedef __str__(self):return '<obj:%s>' % self.nameobj = Foo('obj name') print(obj)
輸出結果:
<obj:A obj>
?
8.__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分別表示獲取、設置、刪除數據
class Foo(object):def __getitem__(self, key):print('__getitem__', key)def __setitem__(self, key, value):print('__setitem__', key, value)def __delitem__(self, key):print('__delitem__', key)obj = Foo()result = obj['k1'] # 自動觸發執行 __getitem__ obj['k2'] = 'name' # 自動觸發執行 __setitem__ del obj['k1'] # 自動觸發執行 __delitem__
輸出結果:
__getitem__ k1
__setitem__ k2 name
__delitem__ k1
?
9.__new__ 、__metaclass__
先看一段代碼:
class Foo(object):def __init__(self, name):self.name = namef = Foo("name") print(type(f)) print(type(Foo))
輸出結果:
<class '__main__.Foo'>
<class 'type'>
?
所以,f對象是Foo類的一個實例,Foo類對象是 type 類的一個實例,即:Foo類對象 是通過type類的構造方法創建
類默認是由 type 類實例化產生,type類中如何實現的創建類?類又是如何創建對象?
類中有一個屬性 __metaclass__,其用來表示該類由 誰 來實例化創建,所以,我們可以為 __metaclass__ 設置一個type類的派生類,從而查看 類 創建的過程。
自定義元類:
class MyType(type):def __init__(cls, *args, **kwargs):print("Mytype __init__", *args, **kwargs)def __call__(cls, *args, **kwargs):print("Mytype __call__", *args, **kwargs)obj = cls.__new__(cls)print("obj ", obj, *args, **kwargs)print(cls)cls.__init__(obj, *args, **kwargs)return objdef __new__(mcs, *args, **kwargs):print("Mytype __new__", *args, **kwargs)return type.__new__(mcs, *args, **kwargs)print('here...')class Foo(object, metaclass=MyType):def __init__(self, name):self.name = nameprint("Foo __init__")def __new__(cls, *args, **kwargs):print("Foo __new__", cls, *args, **kwargs)return object.__new__(cls)f = Foo("Name") print("f", f) print("fname", f.name)
類的生成 調用 順序依次是 __new__ --> __init__ --> __call__
?