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

 

你可能感兴趣的:(python继承和动态属性)