淺談 python的類
剛結束了python的方法,開始看類的時候有點迷糊,類的屬性和方法,對象的屬性和方法,構造函數,傳參。下面就一點點來 分析下。
類(Class) 官方給出的解釋是 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
這裏表示 類裏可以有多個屬性,也可以有多個方法。同時也有自己的字段。
這裏的屬性 官方語言叫做 類變量,屬於這個類的公用部分,誰都可以來用,所以通常不作爲實例變量使用,就是一個符號。而方法,則是在類中
定義的函數,可以理解爲類的行爲部分。
下面展示了類的成員:
普通字段
字段:
靜態字段
普通方法
類成員:方法: 類方法
靜態方法
屬性: 普通屬性
字段: 普通字段屬於對象,靜態字段屬於類,如
class Province:
# 靜態字段
country = '中國'
def __init__(self, name):
# 普通字段 普通字段在每個對象中都要保存一份
self.name = name
# 直接訪問普通字段
obj = Province('河北省')
print obj.name
# 直接訪問靜態字段 靜態字段在內存中只保存一份
Province.country
方法:
class Foo:
def __init__(self, name):
self.name = name
def __init__(self):
pass
def ord_func(self):
""" 定義普通方法,至少有一個self參數 """
# print self.name
print('普通方法')
@classmethod #表示下面的方法是類方法 將類本身作爲對象進行操作的方法
def class_func(cls):
""" 定義類方法,至少有一個cls參數 """
print('類方法')
@staticmethod #標明這是一個靜態方法
def static_func():
""" 定義靜態方法 ,無默認參數"""
print('靜態方法')
# 調用普通方法
f = Foo()
f.ord_func()
# 調用類方法
Foo.class_func()
# 調用靜態方法
Foo.static_func()
屬性:
class Foo:
def func(self):
pass
# 定義屬性
@property
def prop(self):
pass
# ############### 調用 ###############
foo_obj = Foo()
foo_obj.func()
foo_obj.prop #調用屬性
注意:
定義時,在普通方法的基礎上添加 @property 裝飾器;
定義時,屬性僅有一個self參數
調用時,無需括號
方法:foo_obj.func()
屬性:foo_obj.prop
注意:屬性存在意義是:訪問屬性時可以製造出和訪問字段完全相同的假象
屬性由方法變種而來,如果Python中沒有屬性,方法完全可以代替其功能。
實例化:通過類創建出一個對象,叫做實例化一個類。這裏創建出的對象,官方語言是:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法。、
這樣 纔有了類 和對象 兩個概念,類 一般不生成實例變量,當然你可以當做默認值來給他賦值。
比如 A = AA() AA.name 在A中也可以使用,A.name = AA.name 的默認值,如果你賦予了 A.name 值以後,等同於 A.name 覆蓋了AA.name 的值,如果不想要A.name 的值,那麼直接 del A.name
然後再打印 A.name 你會發現 A.name 就是 AA.name 的默認值了,當然,一般情況下不建議把 AA.name 作爲實例變量使用,僅僅是類成員。
就是說 -------- 如果增加了類屬性,實例屬性一定會增加,但是增加了實例屬性,類屬性不受影響
好吧,接下來就是 類中的成員變量的訪問入口,注意,類中創建了成員變量 比如上面的 AA.name 在 AA這個類的方法內是無法直接訪問的,這點和java不同,python 需要一個領路人(self)
通過 self.name 纔可以在類的方法內訪問這個屬性的值。
最需要注意的一點:
如果在類初始化中創建一個變量(或者類初始化的變量) 該變量在類中任何一個方法中被重新修改,那麼無論是其他方法調用還是被實例化的
對象調用,這個變量的值都會隨着改變而改變 下面我們看下他們的name是否改變,結果證實 name 也會隨着變化的。
***之所以不推薦創建類的屬性值 是因爲這個是可變的,並且任何一處定義了都能改變值,維護非常困難,一般建議通過self 來傳值
如:
import datetime as time
class Alarm(object):
alarm_name='不在位指示'
alarm_id=0
alarm_start=time.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
def getAlarmByID(self):
print('根據 告警ID 獲取告警:',self.alarm_id)
return "123"
def testAlarm(self):
print('測試告警信息 alarm_name = ',self.alarm_name,' alarm_id= ',self.alarm_id,' alarm_start=',self.alarm_start)
def test2(self):
print("測試 str 參數 = ",str,' alarm_name= ',self.alarm_name)
self.alarm_name='AIS'
return self.alarm_name
def test3(self):
print(self.alarm_name)
aa = Alarm()
aa.alarm_name = 'R_LOS' #這裏開始修改 alarm_name 的值
aa.test2() #這裏 R_LOS 會取代 不在位指示 同時在方法 test2 中再次修改 alarm_name 的值
print(aa.alarm_name) 這裏最終的值是test2 中修改的 AIS
aa.test3() #不管是 test3裏的打印 還是 aa.alarm_name 的打印,都是 test2 最後修改的那個值 即 AIS
print(aa.alarm_name) # AIS
上述結果說明,在類的方法內部試圖修改類屬性的值是愚蠢的做法,因爲這個是可變的,這樣會導致維護起來非常困難,一般建議通過 self 來傳值
類的繼承: inheritance
Object = Class(SuperClass)
注意: 子類中在對 __init__ 內的變量在其他任何方法上做修改,內外值都會隨着改變
子類重寫了父類的屬性或者方法後,父類的信息都會改變
多重繼承: class A classB c = classC(A,B) 順序按照AB 順序來
Super() 調用顯示父類的屬性或函數 在重寫的時候調用可以延續父類的屬性或方法,子類可選是否借用父類
格式爲: super(父類,參數self).__init__() 父類函數
靜態方法: 使用前提,需要一個參數不能讓別人進行修改,在非特定環境下該靜態變量或方法外部修改無效,只有在特定環境下修改纔可行
如 IND = 'ON'
class Kls(object):
def __init__(self, data):
self.data = data
@staticmethod 表明這是一個靜態方法
def checkind():
IND = "OFF" ### 只有在這裏修改纔有效
return (IND == 'ON') 在別的地方也可以修改這個值 但是在調用這個方法的時候 IND 始終是OFF (已修改) 不會再有別的值
def do_reset(self):
IND = 'OFF' ##這裏修改無效
if self.checkind():
print('Reset done for:', self.data)
def set_db(self):
if self.checkind():
self.db = 'New db connection'
print('DB connection made for: ', self.data)
類方法: @classmethod 表示下面的方法是類方法 將類本身作爲對象進行操作的方法
注意 必須至少有一個參數 cls 來代替 self 其餘自定義
多態: 著名的鴨子測試: 當我們看到一隻鳥走起來像鴨子,游泳起來像鴨子,叫起來也像鴨子,那麼這隻鳥就可以被稱爲鴨子
意思是:一個對象有效的語義,不是由繼承自特定的類或實現特定的接口,而是由當前的方法屬和屬性的集合決定的。
注意: 類型檢查是毀掉多態的利器 type() isinstance() issubclass() 慎用!
類的封裝和私有化: 方法 或者屬性 前面添加上 __ 即可 這樣的話外部無法訪問,但可以通過方法來訪問
如果想在外部訪問私有屬性或方法前添加上 @property 可以直接訪問 對象.屬性
class Person:
__age = int()
def __init__(self,name):
self.name = name
self.__age = 10
@property #################這裏可以直接訪問到了
def age(self):
print(self.name,' 的年齡是:',self.__age)
淺談 python的類和對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.