装饰一个类及内部方法
通過(guò)裝飾器函數(shù)修改一個(gè)類(lèi)屬性
class MyClass:
????NAME = 'My CLASS HAHAHA'
????def __init__(self):
????????pass
print(MyClass.__dict__['NAME'])
My CLASS HAHAHA
等價(jià)于:
def setname(name):
????def warpper(cls):???
????????cls.NAME = name
????????return cls
????return warpper
@setname('MY CLASS enen')??#
class MyClass:
????pass
print(MyClass.__dict__['NAME'])
MY CLASS enen
例2:
class MyClass:
????def foo(self):
????????print('foo')
????def bar():
????????print('bar')
a = MyClass()
a.bar()
報(bào)錯(cuò)如下:
??File "E:\python_project\class_test.py", line 12, in <module>
????a.bar()
TypeError: bar() takes 0 positional arguments but 1 was given
提示最少需要給予一個(gè)參數(shù)才可以
這么寫(xiě)的意思是,函數(shù)是普通函數(shù),但是實(shí)例化之后是無(wú)法使用
這樣是不符合規(guī)定的
改進(jìn):
使用裝飾器,第一個(gè)裝飾器使用類(lèi)方法
@classmethod
class MyClass:
????xxx = 'hahaha'
????def foo(self):
????????print('foo')
????def bar():
????????print('bar')
????@classmethod
????def clsmtd(cls):
????????print('{}.xxx = {}'.format(cls.__name__,cls.xxx))
a = MyClass()
a.foo()
MyClass.bar()
print(MyClass.__dict__)
foo
bar
{'xxx': 'hahaha', 'bar': <function MyClass.bar at 0x0000000000DD0488>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None, 'foo': <function MyClass.foo at 0x0000000000DD0400>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__module__': '__main__', 'clsmtd': <classmethod object at 0x0000000000DD70F0>}
a.clsmtd()
MyClass.xxx = hahaha
靜態(tài)方法使用
staticmethod
class MyClass:
????def foo(slef):
????????return('foo')
????def bar():
????????return('bar')
????@staticmethod
????def staticmtd():
????????return('static')
a = MyClass()
print(MyClass.staticmtd())
print(a.staticmtd())
static
static
是類(lèi)的方法即是所有對(duì)象的方法
py中的靜態(tài)方法,表示最一般的函數(shù)放在靜態(tài)方法中,但是受其管轄
然后測(cè)試bar方法是否可用
????@staticmethod
????def bar():
????????return('bar')
a = MyClass()
print(a.bar())
bar
類(lèi)方法
class Person:
????def haha():
????????print('haha')
Person.haha()
haha
由于沒(méi)有跟self,沒(méi)有完成實(shí)例的綁定,所以不能完成實(shí)例對(duì)象的綁定,所以不能用
Person().haha()
TypeError: haha() takes 0 positional arguments but 1 was given
Person().haha()
語(yǔ)法是對(duì)的,但是禁止這么調(diào)用
@classmethod
class Person:
????HEIGHT = 16
????@classmethod
????def class_method(cls):
????????print('class = {0.__name__} ({0})'.format(cls))
????????cls.HEIGHT = 17
Person.class_method()
print(Person.HEIGHT)
for i in Person.__dict__.items():
????print(i)
返回如下:
class = Person (<class '__main__.Person'>)
17
('class_method', <classmethod object at 0x0000000000DA1278>)
('__weakref__', <attribute '__weakref__' of 'Person' objects>)
('__doc__', None)
('HEIGHT', 17)
('__module__', '__main__')
('__dict__', <attribute '__dict__' of 'Person' objects>)
在類(lèi)定義中,使用@classmethod裝飾器修飾方法
至少有一個(gè)參數(shù),而且第一個(gè)參數(shù)留給了cls,cls表示調(diào)用即類(lèi)對(duì)象自身
cls表示標(biāo)識(shí)符,可以是任意名稱(chēng),但是為了易讀性
類(lèi)方法是可以直接調(diào)用,而實(shí)例的方法要求實(shí)例必須存在,但是類(lèi)存在的時(shí)候?qū)嵗赡懿淮嬖?/span>
只要類(lèi)方法定義過(guò)了,類(lèi)對(duì)象就產(chǎn)生了,那么找屬性即可找到
調(diào)用方法總結(jié)
代碼如下:
class Person:
????def no():
????????print('no')
????def method(self):
????????print('{} method'.format(self))
????@classmethod
????def class_method(cls):
????????print('class = {0.__name__} ({0})'.format(cls))
????????cls.HEIGHT = 170
????@staticmethod
????def static_method():
????????print(Person.HETGHT)
方法調(diào)用
類(lèi)的調(diào)用
print(Person.class_method())
class = Person (<class '__main__.Person'>)
print(Person.static_method())
不能調(diào)用
print(tom.method())
<__main__.Person object at 0x0000000000A97160> method
print(tom.class_method())
class = Person (<class '__main__.Person'>)
print(tom.static_method())
不可以,沒(méi)有傳遞對(duì)象
除了普通方法都可以調(diào)用,但是普通方法都需要對(duì)象的實(shí)例作為第一參數(shù)
實(shí)例可以調(diào)用所有類(lèi)中定義的方法,類(lèi)和靜態(tài)方法
訪問(wèn)控制
訪問(wèn)控制主要為了保護(hù)封裝不被破壞,但是python對(duì)外是可見(jiàn)的
私有屬性
屬性名前加入兩個(gè)下劃線表示當(dāng)前方法不被破壞
class Person:
????age = 3
????height = 170
????def __init__(self,name,age=18):
????????self.name = name
????????self.age = age
????def growup(self,incr=1):
????????if 0 < incr < 150:
????????????self.__age + incr
tom = Person('tom')
tom.age = 200
class Person:
????age = 3
????height = 170
????def __init__(self,name,age=18):
????????self.name = name
????????self.age = age
????def growup(self,incr=1):
????????if 0 < incr < 150:
????????????self.__age + incr
????def getage(self):
????????return self.__age
print(Person('tom').getage)
<bound method Person.getage of <__main__.Person object at 0x0000000000827208>>
class Person:
????def __init__(self,name,age=18):
????????self.name = name
????????self.__age = age
????def growup(self,incr=1):
????????if 0 < incr < 150:
????????????self.__age += incr
????# 獲取內(nèi)部屬性
????def getage(self):
????????return self.__age
tom = Person('tom')
tom.growup(10)
print(tom.getage())
28
修改tom._Person__age
print(tom.getage())
tom._Person__age = 200
print(tom.getage())
200
查看tom.__dict__
print(tom.__dict__)
{'_Person__age': 200, 'name': 'tom'}
得到的字典中,其實(shí)是新加了一個(gè)key,而并非被覆蓋
所以py的外界是可以修改的隱藏方法的
新增加key:
tom._Person__ages = 200
print(tom.getage())
print(tom.__dict__)
{'name': 'tom', '_Person__age': 20, '_Person__ages': 200}
私有變量的本質(zhì)
使用__變量名 時(shí),會(huì)將其改名,轉(zhuǎn)為_(kāi)類(lèi)名+前綴,所以原來(lái)名字訪問(wèn)不到了
知道了這個(gè)名稱(chēng)則可以直接修改
print(a.__dict__)
{'name': 'tom', '_Person__age': 19}
保護(hù)變量
在變量前加一個(gè)下劃線,共同的約定,表示提醒你這個(gè)是一個(gè)內(nèi)部私有的
而解釋器認(rèn)為私有的是私有變量
總結(jié)
以上是生活随笔為你收集整理的装饰一个类及内部方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python基础===PEP网站,代码规
- 下一篇: jquery.cookie.js 使用小