溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python類的定義繼承調(diào)用方法有哪些

發(fā)布時(shí)間:2022-06-23 13:58:54 來源:億速云 閱讀:205 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“Python類的定義繼承調(diào)用方法有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Python類的定義繼承調(diào)用方法有哪些”吧!

    一、類的約束

    # _開頭: 私有變量;
    # __開問: 私有變量,不能被繼承;
    # __xxx__: 能被訪問,不能被繼承;
    class A:
    def __init__(self):
    self._internal = 0 # 私有變量不能被訪問
    self.public = 1 # 可被訪問
    def public_method(self):
    pass
    def _private_method(self): # 私有方法不能被訪問
    pass
    class B:
    def __init__(self):
    self.__private = 0 # 這個(gè)屬性會(huì)在內(nèi)存中被重新命名為_B__private
    
    def __private_method(self): # 不能被訪問,不能被繼承
    pass
    def __private_method__(self): # 能被訪問,不能被繼承
    pass

    二、類的定義

    2.1、創(chuàng)建創(chuàng)建

    class Dog:
    a = "0"; #相當(dāng)于public static變量,全局的
    """__init__是一個(gè)默認(rèn)的方法,且self為默認(rèn)的,用self修飾的屬性為public類型的類變量"""
    def __init__(self, name, age):
    self.name = name
    self.age = age
    self.sex = "1";#設(shè)置屬性默認(rèn)值
    
    def sit(self):
    print(self.name + "is now sitting" + "and sex is " + self.sex + Dog.a)
    
    @classmethod
    def user_name(cls, name): #注意這種注解的用法
    return cls()
    
    dog = Dog("kk", 12);
    dog.sit()
    2.1.1、類的導(dǎo)入

    在python中分為文件、模塊、類,其中文件和模塊可劃等價(jià);所以導(dǎo)入有幾種方式,比如dog.py文件中定義了兩個(gè)Class,則在使用類中導(dǎo)入方法有以下幾種:

    • from car import Dog;#導(dǎo)入一個(gè)模塊中的特定類,使用時(shí)則直接Car();

    • import car;#導(dǎo)入一個(gè)模塊中的所有類,使用時(shí)則需要car.Car();

    • from car import *;#不推薦,容易引起命名沖突問題

    from collections import OrderedDict; #使用標(biāo)準(zhǔn)類庫(kù)
    t = OrderedDict();
    2.1.2、構(gòu)造器
    class Date:
    # Primary constructor
    def __init__(self, year, month, day):
    self.year = year
    self.month = month
    self.day = day
    
    # Alternate constructor
    @classmethod
    def today(cls):
    t = time.localtime() #它接收一個(gè)class作為第一個(gè)參數(shù),它被用來創(chuàng)建并返回最終的實(shí)例, 這個(gè)cls==__init__
    return cls(t.tm_year, t.tm_mon, t.tm_mday)
    
    a = Date(2020, 5, 10) # Primary
    b = Date.today() # Alternate

    減少構(gòu)造函數(shù)的參數(shù)個(gè)數(shù):

    class Structure1:
    # Class variable that specifies expected fields
    _field_list = []
    
    def __init__(self, *args):
    if len(args) != len(self._field_list):
    raise TypeError(f'Expected {len(self._field_list)} arguments')
    # Set the arguments
    for name, value in zip(self._field_list, args):
    setattr(self, name, value)
    
    # Example class definitions
    class Course(Structure1):
    # 這行只是為了一個(gè)準(zhǔn)許入判斷,沒有太多實(shí)際意思,或是一個(gè)聲明
    _field_list = ['course_name', 'total_class', 'score']
    
    c = Course('python', 30, 0.3);

    關(guān)鍵字參數(shù)

    class Structure2:
    _field_list = []
    
    def __init__(self, *args, **kwargs):
    if len(args) > len(self._field_list):
    raise TypeError(f'Expected {len(self._field_list)} arguments')
    # Set all of the positional arguments
    for name, value in zip(self._field_list, args):
    setattr(self, name, value)
    
    # Set the remaining keyword arguments
    #是通過pop這種方式來檢查的,在長(zhǎng)度范圍內(nèi)如果pop出錯(cuò)則拋異常
    for name in self._field_list[len(args):]:
    setattr(self, name, kwargs.pop(name))
    
    # Check for any remaining unknown arguments
    if kwargs:
    raise TypeError(f"Invalid argument(s): {','.join(kwargs)}")
    
    # Example use
    class Course(Structure2):
    _field_list = ['course_name', 'total_class', 'score']
    
    course_1 = Course('python', 30, 0.3)
    course_2 = Course('python', 30, score=0.3)
    course_3 = Course('python', total_class=30, score=0.3)

    擴(kuò)展關(guān)鍵字參數(shù):

    class Structure3:
    # Class variable that specifies expected fields
    _field_list = []
    
    def __init__(self, *args, **kwargs):
    if len(args) != len(self._field_list):
    raise TypeError(f'Expected {len(self._field_list)} arguments')
    
    # Set the arguments
    for name, value in zip(self._field_list, args):
    setattr(self, name, value)
    
    # Set the additional arguments (if any)
    extra_args = kwargs.keys() - self._field_list
    for name in extra_args:
    setattr(self, name, kwargs.pop(name))
    
    if kwargs:
    raise TypeError(f"Duplicate values for {','.join(kwargs)}")
    
    # Example use
    if __name__ == '__main__':
    class Course(Structure3):
    _field_list = ['course_name', 'total_class', 'score']
    
    course_1 = Course('python', 30, 0.3)
    course_2 = Course('python', 30, 0.3, date='8/5/2020')
    2.1.3、類屬性

    要?jiǎng)?chuàng)建一個(gè)新的實(shí)例屬性,可以通過描述器的形式來定義它的功能,一個(gè)描述器就是一個(gè)實(shí)現(xiàn)了3個(gè)核心屬性訪問操作的類,分別對(duì)應(yīng)get\set\delete這三個(gè)特殊的方法。

    # Descriptor attribute for an integer type-checked attribute
    class Integer:
    def __init__(self, name):
    self.name = name
    """下面三個(gè)方法只是一個(gè)更嚴(yán)格的定義,可以不需要,要使用上面的描述器,需要把描述器放入到一個(gè)class中,這樣所有對(duì)描述器的訪問都會(huì)被get/set/delete所捕獲"""
    def __get__(self, instance, cls):
    if not instance:
    return self
    else:
    return instance.__dict__[self.name]
    def __set__(self, instance, value):
    if not isinstance(value, int):
    raise TypeError('Expected an int object')
    instance.__dict__[self.name] = value
    def __delete__(self, instance):
    del instance.__dict__[self.name]

    示例1:

    class Point:
    """實(shí)例變量,和下面的x,y不是一回事"""
    x = Integer('x')
    y = Integer('y')
    
    def __init__(self, x, y):
    self.x = x
    self.y = y
    print(Point.x.name) # x
    point = Point(3, 5)
    print(f'point x = {point.x}') #3
    print(f'point y = {point.y}') #5
    point.y = 6
    print(f'after change,point y = {point.y}') #6

    三、類的繼承

    ptyhon在實(shí)現(xiàn)繼承時(shí)會(huì)用一個(gè)叫MRO列表的算法實(shí)現(xiàn),它有三條規(guī)則:1、子類會(huì)先于父類;2、多個(gè)父類會(huì)根據(jù)它們?cè)诹斜碇械捻樞虮粰z查;3、如果對(duì)下一個(gè)類有兩個(gè)合法的選擇,則返回第一個(gè)合法的父類;

    3.1、單繼承

    class A:
    def __init__(self):
    self.x = 0
    class B(A):
    def __init__(self):
    super().__init__() #這行需要注意,也可以不寫,但不寫時(shí)就不會(huì)調(diào)用父類的init方法
    self.y = 1

    3.2、多繼承

    class Base:
    def __init__(self):
    print('call Base.__init__')
    class A(Base):
    def __init__(self):
    Base.__init__(self)
    print('call A.__init__')
    
    class B(Base):
    def __init__(self):
    Base.__init__(self)
    print('call B.__init__')
    """多繼承的實(shí)現(xiàn)"""
    class C(A,B):
    def __init__(self):
    A.__init__(self)
    B.__init__(self)
    print('call C.__init__')
    c = C()
    # call Base.__init__
    # call A.__init__
    # call Base.__init__
    # call B.__init__
    # call C.__init__

    3.3、調(diào)用父類方法

    class Proxy:
    def __init__(self, obj):
    self._obj = obj
    
    def __getattr__(self, name):
    return getattr(self._obj, name)
    
    def __setattr__(self, name, value):
    if name.startswith('_'):
    """調(diào)用父類方法"""
    super().__setattr__(name, value)
    else:
    setattr(self._obj, name, value)
    
    proxy = Proxy({})
    proxy.__setattr__("_name", "hm")

    3.4、屬性擴(kuò)展

    3.4.1、完全擴(kuò)展
    # 父類
    class Person:
    def __init__(self, name):
    self.name = name
    
    # defined Getter function, auto to call the sign name.setter when it be build
    @property
    def name(self):
    return self._name
    
    # defined Setter function
    @name.setter
    def name(self, value):
    if not isinstance(value, str):
    raise TypeError('Expected a string')
    self._name = value
    
    # defined Deleter function
    @name.deleter
    def name(self):
    raise AttributeError("Can't delete attribute")
    
    """子類"""
    class SubPerson(Person):
    @property
    def name(self):
    print('Getting name')
    return super().name
    
    @name.setter
    def name(self, value):
    print(f'Setting name to {value}')
    super(SubPerson, SubPerson).name.__set__(self, value)
    
    @name.deleter
    def name(self):
    print('Deleting name')
    super(SubPerson, SubPerson).name.__delete__(self)
    
    """測(cè)試"""
    sub_person = SubPerson('Guido')
    print(f'name is: {sub_person.name}')
    3.4.2、單獨(dú)擴(kuò)展
    class SubPerson(Person):
    @Person.name.getter
    def name(self):
    print('Getting name')
    return super().name # or super(SubPerson, SubPerson).name.__set__(self, value)
    sub_p = SubPerson('Bill')
    #不能用property的原因是,property其實(shí)是get、set、del函數(shù)的集合,各有各的用處。下面才是正確的擴(kuò)展方式,所以下面的代碼是不工作的
    class SubPerson(Person):
    @property # Doesn't work
    def name(self):
    print('Getting name')
    return super().name
    #如果要用property屬性則要用下面的編碼實(shí)現(xiàn)
    class SubPerson(Person):
    @property
    def name(self):
    print('Getting name')
    return super().name
    @name.setter
    def name(self, value):
    print(f'Setting name to {value}')
    super(SubPerson, SubPerson).name.__set__(self, value)
    @name.deleter
    def name(self):
    print('Deleting name')
    super(SubPerson, SubPerson).name.__delete__(self)

    四、類的調(diào)用

    import time
    class Date:
    # Primary constructor
    def __init__(self, year, month, day):
    self.year = year
    self.month = month
    self.day = day
    # Alternate constructor
    @classmethod
    def today(cls):
    t = time.localtime() #它接收一個(gè)class作為第一個(gè)參數(shù),它被用來創(chuàng)建并返回最終的實(shí)例, 這個(gè)cls==__init__
    return cls(t.tm_year, t.tm_mon, t.tm_mday)
    """普通調(diào)用"""
    c = Date(2010, 12, 12)
    
    """類方法在繼承中使用"""
    class NewDate(Date):
    pass
    c = Date.today() # Creates an instance of Date (cls=Date)
    d = NewDate.today() # Creates an instance of NewDate (cls=NewDate)

    五、抽象類

    from abc import ABCMeta, abstractmethod
    class IStream(metaclass=ABCMeta):
    @abstractmethod
    def read(self, max_bytes=-1):
    pass
    @abstractmethod
    def write(self, data):
    pass
    """不能被實(shí)例化"""
    #a = IStream()
    
    class SocketStream(IStream):
    def read(self, max_bytes=-1):
    pass
    def write(self, data):
    pass
    """檢查"""
    def serialize(obj, stream):
    if not isinstance(stream, IStream):
    raise TypeError('Expected an IStream')
    pass

    5.1、強(qiáng)制類型檢查

    from abc import ABCMeta, abstractmethod
    class IStream(metaclass=ABCMeta):
    @abstractmethod
    def read(self, max_bytes=-1):
    pass
    @abstractmethod
    def write(self, data):
    pass
    import io
    # Register the built-in I/O classes as supporting our interface
    IStream.register(io.IOBase)
    
    # Open a normal file and type check
    f = None #open('test.txt')
    print(f'f object is IStream type: {isinstance(f, IStream)}')
    #f object is IStream type: False

    六、類的比較

    from functools import total_ordering
    class Room:
    def __init__(self, name, length, width):
    self.name = name
    self.length = length
    self.width = width
    self.square_feet = self.length * self.width
    @total_ordering
    class House:
    def __init__(self, name, style):
    self.name = name
    self.style = style
    self.rooms = list()
    @property
    def living_space_footage(self):
    return sum(r.square_feet for r in self.rooms)
    def add_room(self, room):
    self.rooms.append(room)
    def __str__(self):
    return f'{self.name}: {self.living_space_footage} square foot {self.style}'
    def __eq__(self, other):
    return self.living_space_footage == other.living_space_footage
    
    def __lt__(self, other):
    return self.living_space_footage < other.living_space_footage
    # Build a few houses, and add rooms to them
    h2 = House('h2', 'Cape')
    h2.add_room(Room('Master Bedroom', 14, 21))
    h2.add_room(Room('Living Room', 18, 20))
    h2.add_room(Room('Kitchen', 12, 16))
    h2.add_room(Room('Office', 12, 12))
    
    h3 = House('h3', 'Ranch')
    h3.add_room(Room('Master Bedroom', 14, 21))
    h3.add_room(Room('Living Room', 18, 20))
    h3.add_room(Room('Kitchen', 12, 16))
    
    h4 = House('h4', 'Split')
    h4.add_room(Room('Master Bedroom', 14, 21))
    h4.add_room(Room('Living Room', 18, 20))
    h4.add_room(Room('Office', 12, 16))
    h4.add_room(Room('Kitchen', 15, 17))
    houses = [h2, h3, h4]
    
    print(f'Is {h2} bigger than {h3}: {h2 > h3}')
    print(f'Is {h3} smaller than {h4}: {h3 < h4}')
    print(f'Is {h3} greater than or equal to {h2}: {h3 >= h2}')
    print(f'Which one is biggest in houses: {max(houses)}')
    print(f'Which is smallest in houses: {min(houses)}')
    
    """"""
    # Is h2: 990 square foot Cape bigger than h3: 846 square foot Ranch: True
    # Is h3: 846 square foot Ranch smaller than h4: 1101 square foot Split: True
    # Is h3: 846 square foot Ranch greater than or equal to h2: 990 square foot Cape: False
    # Which one is biggest in houses: h4: 1101 square foot Split
    # Which is smallest in houses: h3: 846 square foot Ranch
    # """"""
    class House:
    def __eq__(self, other):
    pass
    def __lt__(self, other):
    pass
    # Methods created by @total_ordering
    __le__ = lambda self, other: self < other or self == other
    __gt__ = lambda self, other: not (self < other or self == other)
    __ge__ = lambda self, other: not (self < other)
    __ne__ = lambda self, other: not self == other

    感謝各位的閱讀,以上就是“Python類的定義繼承調(diào)用方法有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Python類的定義繼承調(diào)用方法有哪些這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI