python繼承和動態屬性


一、私有屬性

私有屬性: __開頭或者_開頭,即雙下划線開頭的叫做私有屬性,不能再類外部使用,只能在類里面使用

私有方法:__開頭或者_開頭

注意點:以后看到_下划線開頭的屬性或者方法,都不要去動或者使用

class SOS:
    attr = 100
    _attr = 222  # 這是單下划線,在外部訪問,但是不要在類外部使用
    __attr = 999   # 這是雙下划線,強制拒絕外部訪問


print(SOS.attr)   # 打印出 100
print(SOS.__attr)    # 報錯!!!因為是私有屬性,所以訪問不到

二、繼承

# 默認繼承
class 類名:
  pass

class 類名(繼承的父類):
  pass

object(基類):python中所有類的祖宗(所有的類都繼承於它)

繼承:子類通過繼承能夠擁有父類的屬性和方法(私有屬性和私有方法除外)

class BaseClass:
    attr = "base"

    def func(self):
        print("--------base---func---------")


class MyClass(BaseClass):
    def func2(self):
        print("--------自己的的func2---------")


# 實例化一個對象m
m = MyClass()
print(m.attr)  # 打印出  base
m.func()  # 打印出 --------base---func---------

m.func2()  # 打印出 --------自己的的func2---------

2.1 繼承示例

# 案例一:通過繼承方法去實現
# 手機一代
# 手機二代
# 手機三代

# 1995年的手機
class PhoneV1:
    """手機一代"""

    def __init__(self, name):
        self.name = name

    def call_phone(self):
        print(f"{self.name}使用了打電話的功能")


# 2002年的手機
class PhoneV2(PhoneV1):
    """手機二代"""

    def listen_music(self):
        print(f"{self.name}使用了聽音樂的功能")

    def send_msg(self):
        print(f"{self.name}使用了發短信的功能")


# 2010年的手機
class PhoneV3(PhoneV2):
    """手機三代"""

    def game(self):
        print(f"{self.name}使用了玩游戲的功能")

    def pay(self):
        print(f"{self.name}使用了支付的功能")


m = PhoneV3("oppo")
m.call_phone()  # oppo使用了打電話的功能

2.2 重寫父類方法

重寫父類方法(重點!!!):在子類中定義一個和父類重名的方法,工作中常用

class Base(object):
    def base_func(self):
        print("----Base----base_func---------")


class A(Base):
    def base_func(self):
        print("----A子類----base_func---------")

        # 方式一:父類名.方法名(self)
        Base.base_func(self)
        # 方式二:super().方法名
        super().base_func()

# 實例化對象a
a = A()
# 調用子類中的自己的方法,雖然重寫了方法,但會直接覆蓋,會調用子類的方法
a.base_func()   # 打印出 ----A子類----base_func---------

# 如果想調用父類中的方法呢?怎么辦?

 

重寫方法的實際應用場景:看下面的代碼

應用場景:
  父類原有的方法不能滿足原有的需求,需要對父類中的方法進行擴展

開放封閉原則:
  已經實現的功能不要進行修改(對修改是封閉的)
  對擴展的功能是開放的

class BaseClass(object):
    # 姓名、身高
    def __init__(self, name, height):
        self.name = name
        self.height = height


class MyClass(BaseClass):
    # 姓名、身高、年齡、性別
    def __init__(self, name, height, age, sex):
        # 調用父類的方法
        super().__init__(name, height)
        # 重寫之后擴展的功能代碼
        self.age = age
        self.sex = sex

    def func(self):
        pass


# 實例化對象c
c = MyClass("jack", 172, 18, "boy")
print(c)
# ----------------------------------------上面是代碼-------------------------------------------------------------

# ---------------------------------------下面是截圖解析---------------------------------------------------

三、屬性動態設置

動態設置屬性:
  1、setattr(obj,屬性名,屬性值):在代碼執行的過程中給 類/對象 設置屬性,(屬性不存在就是添加,存在就是修改
      這個obj可以是類也可以是對象
  2、getattr(obj,屬性名,默認值):在代碼執行的過程中獲取 類/對象屬性
  3、delattr(obj,屬性名):在代碼執行的過程中刪除 類/對象屬性

3.1 setattr

setattr(obj,屬性名,屬性值):在代碼執行的過程中給 類/對象 設置屬性,(屬性不存在就是添加,存在就是修改)

class BaseClass(object):
    # 姓名、身高
    def __init__(self, name, height):
        self.name = name
        self.height = height


# 動態設置類屬性(這種不建議使用)
BaseClass.attr = 18
BaseClass.attr2 = 185
print(BaseClass.attr)  # 打印 18
# __dict__ 可以查看所有的屬性
print(BaseClass.__dict__)
# 1.setattr()
setattr(BaseClass, "attr3", 99)
print(BaseClass.attr3)  # 打印 99

# 如何將變量的值設置為類屬性名
var = input("請輸入屬性名:")
value = "8899"
setattr(BaseClass, var, value)
print(BaseClass.__dict__)

# 給對象動態設置屬性
b1 = BaseClass("tom", "")
setattr(b1, "weight", 60)
print(b1.__dict__)  # 打印出  {'name': 'tom', 'height': '男', 'weight': 60}

 

3.2 getattr

getattr(obj,屬性名,默認值):在代碼執行的過程中獲取 類/對象屬性

class BaseClass(object):
    # 姓名、性別
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex


b1 = BaseClass("湯姆", "")
# 需求:根據用戶輸入的屬性名,獲取對應的屬性值
item = input("請輸入一個屬性名:")
res1 = getattr(b1, item, "None")  # 這里的第三個參數,可以自己設置成一個默認值
print(res1)   # 打印為 {'name': '湯姆', 'sex': '男'}

 

3.3 delattr

delattr(obj,屬性名):在代碼執行的過程中刪除 類/對象屬性

class BaseClass(object):
    # 姓名、性別
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex


b2 = BaseClass("湯姆", "")
# 需求:根據用戶輸入的屬性名,刪除對應的屬性值
item2 = input("請輸入一個屬性名:")
delattr(b2, item2) print(b2.__dict__)  # 打印為 {'sex': '男'},已經將name屬性刪掉了

接下來看一個簡單的案例:

# 需求:打印出name之外的所有屬性
class BaseClass(object):
    # 姓名、性別、年齡
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age


b3 = BaseClass("拖米", "", 25)
setattr(b3, "aa", 11)
setattr(b3, "bb", 22)
setattr(b3, "cc", 33)
print(b3.__dict__)  # 打印結果為{'name': '拖米', 'sex': '男', 'age': 25, 'aa': 11, 'bb': 22, 'cc': 33}

keys = b3.__dict__.keys()
for key in keys:
    if key != "name":
        print(getattr(b3, key))   # 打印出  男、25、11、22、33

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM