Python類Class的簡單介紹,繼承、靜態方法和類方法、magic方法
阿新 • • 發佈:2020-12-08
Python類Class的簡單介紹,繼承、靜態方法和類方法、magic方法
1.繼承
# -*-coding:utf-8 -*- """ 在繼承中,父類的構造方法(__init__()方法)不會自動呼叫,需要在子類的構造方法中專門呼叫 在呼叫父類的方法時需要加上父類的類名字首,並帶上 self 引數變數 在 Python 中,首先查詢對應型別的方法,如果在子類中找不到對應的方法,才到父類中去查詢。若繼承多個父類,則按先後順序查詢 """ # 父類 class People: # 定義基本屬性 name = '' # 定義私有屬性,私有屬性在類外部無法直接進行訪問 __weight = 0 # 定義構造方法 def __init__(self, name, weight): self.name = name self.__weight = weight def speak(self): print("【父類方法】我叫 %s, 體重是 %s 千克" % (self.name, self.__weight)) # 公共方法 def public_method(self): print("我是父類的公共方法") return self.name # 私有方法 def __private_method(self): print("我是父類的私有方法") return self.name # 繼承 class Student(People): grade = '' def __init__(self, name, weight, grade): # 呼叫父類的構造方法 People.__init__(self, name, weight) self.grade = grade # 複寫父類speak方法 def speak(self): print("【子類方法】我叫 %s, 我上 %s 年級" % (self.name, self.grade)) s = Student('小明', 40, 5) s.speak() # 輸出: 【子類方法】我叫 小明, 我上 5 年級 # s.public_method() # 輸出:我是父類的公共方法 # s.__private_method() # 此句報錯,子類例項無法訪問父類中的私有方法
2.類方法和靜態方法
# -*- utf-8 -*- """ Python繼承 """ class A: @staticmethod # 靜態方法,可以直接通過 型別.方法名訪問 def static_method(): print("我是一個靜態方法") # @classmethod # 類方法,可以直接通過 型別.方法名訪問 def class_method(cls): print("我是一個類方法") A.static_method() # A.class_method() # 若不用 @classmethod 修飾,則需要通過建立例項訪問方法 a = A() a.class_method()
3.Python類中的magic方法
# -*-coding:utf-8 -*- """ Python類中的一些magic方法介紹,可以通過複寫這些方法,實現特殊的功能 """ from array import array import math import sys class Vector2d: code = 'd' def __init__(self, x, y): print('當前函式名稱:', sys._getframe().f_code.co_name) # 吃語句用於列印當前方法名稱,用於觀察magic方法呼叫順序 self.__x = float(x) # 兩個前導下劃線,把屬性標記為私有的 self.__y = float(y) @property # @property裝飾器把讀值方法標記為特性, 只讀 def x(self): # 讀值方法與公開屬性同名,都是x print('當前函式名稱:', sys._getframe().f_code.co_name) return self.__x @property def y(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return self.__y # 迭代 def __iter__(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return (i for i in (self.x, self.y)) def __repr__(self): print('當前函式名稱:', sys._getframe().f_code.co_name) class_name = type(self).__name__ return '{}({!r}, {!r})'.format(class_name, *self) # {!r} 類似於 %r def __str__(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return str(tuple(self)) def __bytes__(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return bytes([ord(self.typecode)]) + bytes(array(self.typecode, self)) # ord返回對應的ASCII碼 # equals, 必須要實現__hash__方法 def __eq__(self, other): print('當前函式名稱:', sys._getframe().f_code.co_name) return tuple(self) == tuple(other) def __hash__(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return hash(self.x) ^ hash(self.y) def __abs__(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return math.hypot(self.x, self.y) # hypot() 返回歐幾里德範數 sqrt(x*x + y*y) def __bool__(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return bool(abs(self)) def angle(self): print('當前函式名稱:', sys._getframe().f_code.co_name) return math.atan2(self.y, self.x) # atan2() 返回給定的 X 及 Y 座標值的反正切值 def __format__(self, fmt_spec=''): print('當前函式名稱:', sys._getframe().f_code.co_name) if fmt_spec.endswith('p'): # 如果格式程式碼以'p'結尾,使用極座標,否則構建直角座標 fmt_spec = fmt_spec[:-1] coords = (abs(self), self.angle()) outer_fmt = '<{}, {}>' else: coords = self outer_fmt = '({}, {})' components = ((format(c, fmt_spec)) for c in coords) return outer_fmt.format(*components) if __name__ == '__main__': v = Vector2d(2, 3) # if v == (2, 3): # pass # print(abs(v)) # if v: # print(True) # print(v) # str(v) # type(v) # print(type(v)) # print(v.x) # v.x = 10 # print(v.x) # set(v) # print(bytes(v)) # print(format(v, '.3p')) # print(format(v, '.3f')) # print(abs(v)) # v.frombytes('1234') # if v: # pass