python之类的属性和方法的私有化

本文深入探讨Python中的封装和继承概念,包括私有属性保护、方法重写、多继承及多态特性,揭示类属性与实例属性的区别,以及类方法、实例方法和静态方法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

保护对象的属性(封装)

如果有一个对象,当需要对其进行修改属性时,有二种方法:

  • 对象名.属性名 = 数据 ------>直接修改;
  • 对象名.方法名()------->间接修改;

为了更好的保护属性安全,既不能随意修改,一般的处理方式为:

  • 将属性定义为私有属性;
  • 添加一个可以调用的方法,供调用;
class User:

    def __init__(self,pw):
        if len(pw) >=6:
            self.__password = pw
        else:
            print("密码:%s,密码不符合规定"%pw)
    def __str__(self):
        return "密码%s"%self.__password

    def get_password(self):
        return self.__password

u1 = User("123456")
print(u1.get_password())
print(u1)


123456
密码:123456

__del__( )方法

当创建一个对象后,python解释器默认调用__init__()方法;

当删除一个对象时,python解释器也会默认调用一个方法,即__del__( )方法;

  • 当有一个变量保存了对象的引用时,此对象的引用计数就会加1;
  • 当使用del删除变量指向的对象时,如果对象的引用计数不是1,比如3.那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再次调用del时,变为1,如果再次调用1次del,此时真的把对象进行删除;
  • 当整个程序执行完成之后,此时的对象一定会被删除;

(单)继承

在程序中,继承描述的事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫。

class Animal:

    def __init__(self):
        self.name="动物"    
    def eat(self):
        print("-----吃饭-----")
    def sleep(self):
        print("-----睡觉-----")

class Dog(Animal):

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

    def shout(self):
        print("-----大叫-----")
    
class Cat(Animal):

#    def __init__(self):
#        print("猫初始化了")
    
    def catch(self):
        print("-----抓老鼠-----")

class Zangao(Dog):
    def fight(self):
        print("-----战斗------")

dog = Dog()
dog.eat()
print(dog.name)

#cat = Cat()
#print(cat.name)

za = Zangao()
za.eat()



-----吃饭-----
动物
-----吃饭-----
动物

切记:私有属性不能被继承

多继承

所谓多继承,即子类有多个父类,并且具有它们的特征。

# 定义第一个父类

class A:

    def test(self):
        print("------A------")
    
#定义第二个父类
class B:

    def test(self):
        print("------B------")

#第一个子类
class C(A,B):  # A和B写的顺序跟优先级是有关系的

    def test1(self):
        print("------C-------")

c = C()
print(C.__mro__) #获得多继承的优先级的顺序;
c.test()




(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class
'object'>)
------A------

注意:object:默认情况下都一个父类就是object,之前所有的特殊方法都是继承父类object;

重写父类方法与调用父类方法

class Animal:
    
    # 父类定义init方法
    def __init__(self):
        print("动物初始化了")
        self.__name = "动物"
        self.color = "yellow"    
    def eat(self):
        print("-----吃饭-----")
    def sleep(self):
        print("-----睡觉-----")

class Dog(Animal):

    # init和父类的init名字一样,所以叫方法的重写
    def __init__(self,name):
    super().__init()   # 主动调用父类的init方法
        print("狗被初始化了")
        self.name=name

    def shout(self):
        print("-----大叫-----")
    
class Cat(Animal):

#    重写父类的init方法
#    def __init__(self):
#        print("猫初始化了")
    
    def catch(self):
        print("-----抓老鼠-----")

class Zangao(Dog):
    def fight(self):
        print("-----战斗------")

dog = Dog("小白") #如果子类中对某个方法重写了,优先调用子类自己本身的方法


动物初始化了
狗被初始化了
小白
yellow

多态

python是一个弱所谓多态,定义时的类型和运行时的类型不一样,此时就成为多态;python是一个弱语言,所以对于多态表现的不明显。

什么是类属性和实例属性?

在之前的例子中我们接触到的就是实例属性(对象属性),顾名思义,类属性就是类对象所拥有的属性,他被所有类对象的实例对象所共有,在内存中只存在一个副本。对于公有类属性,在类外可以通过类对象和实例对象访问。

# 类属性:所属类,这个类下所有的对象都可以共享这个类属性。

class User():
    name ="xihu" # 公共的类属性
    __passward = "123456" # 私有的类属性 

    def __init__(self,sex,username):
        self.sex = sex
        self.username = username

class WeChat_User(User):
    pass

re = User("男","lanjing")
print(re.name)
print(re.sex)
print(re.username)

print(WeChat_User.name)#name从父类继承过来的,name属于类属性。可以直接通过类的对象来访问
print(re.name)

#类属性的修改,只能通过类属性修改
User.name = "xiaoli" #真正的类属性修改
u.name = "xili" #本质上没有修改类属性。仅仅给对象定义了一个对象属性name。并且赋值“xiaoli”
del re.name #本质上删除了对象的name属性,并没有删除类的属性。

xihu
男
lanjing
xihu
xili     # 这不是修改类属性name

总结:

如果需要在类外修改类属性,必须通过类对象去引用后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称属性,实例属性会强制屏蔽掉类属性,即引用的实例属性,除非删除了该实例属性。

属性叫法变量叫法描述
类属性类变量所有对象共享同一份类属性
实例属性成员变量每个不同对象,有不一样值的实例属性

定义类方法

class A(object):
    name = "zs"
    
    def test1(self):
        print("----A 的test1的方法")
    
    @classmethod #类方法一定要在方法上面加一个修饰器,类方法的参数cls,代表当前的类
    def test2(cls):
         cls.name = "xiaoli"
         print("----A 的test2的方法")

    @staticmethod#静态方法,属于类。没有默认传递的参数,可以通过类对象来调用,也可以通过类名来调用
    def test3():
        A.name = "ls"  
        print("------A的test3静态方法")


a = A()
a.test2()
A.test2()
A.test3()
print(A.name)  

----A 的test2的方法
----A 的test2的方法
xiaoli

静态方法

    类方法的一种,有专门的修饰器,如上。

总结:

从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法第一个参数是类的对象cls,那么通过cls引用必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也可能是实例属性属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先等级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。

方法类名语法描述
类方法@classmethod第一个形参cls,默认传递
静态方法@staticmethod没有默认传递的形参
对象方法(成员方法)def 方法名第一个形参self,默认传递
特殊方法名默认参数功能描述
_init__()self 
__str__()self 
__del__()self 
__new__()cls 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值