1. 程式人生 > 其它 >Python類Class的簡單介紹,繼承、靜態方法和類方法、magic方法

Python類Class的簡單介紹,繼承、靜態方法和類方法、magic方法

技術標籤:pythonpython繼承

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