python3-私有成员和魔法方法

本文探讨了如何通过私有成员保护类的内部细节,以及魔法方法在类设计中的特殊作用,如__doc__, __init__, 和__getattr__/__setattr__等。了解这些概念有助于增强代码的封装性和可维护性。
摘要由CSDN通过智能技术生成

系列文章目录

一、私有成员

类内部的成员可以通过实例或类名进行调用,但我们不希望所有的变量和方法能被外部访问。对于有些成员,我们希望能限制对它们的访问。以提高程序的可靠性。

  • 含义:

    私有成员只能在类的内部访问,外部无法访问。

  • 格式:

    在成员的名字前加上两个下划线__,这个成员就变成了一个私有成员

    class Foo:
        def __init__(self):
            self.__name = 'Hugh'
            
    foo = Foo()
    # foo.__name 会报错
    
  • 访问私有成员:

    如果想要从外部访问私有成员,就在类内部定义get和set方法,专门用于获取和修改私有成员。

    方法名不是固定的,重要的是见名知意:

    class Foo:
        def __init__(self):
            self.__name = 'Hugh'
            
        def get_name(self):
            return self.__name
        
        def set_name(self, name)
        	self.__name = neme        
    
  • 还有一些以一个下划线开头的成员,它可以被外部访问,但这样写的意思是,尽量将它当作一个私有成员来使用。

二、魔法方法

还有一种以双下划线开头并结尾的成员,被称为“魔法方法”或“魔法属性”。这些是有专门用途的成员,尽量不要自己创造这类成员。

常用的魔法方法和属性:

  • __doc__:说明性文档和信息。

    class Foo:
        """ 描述类信息,可被自动收集 """
    	pass
    
    print(Foo.__doc__)  # 打印:描述类信息,可被自动收集
    
  • __init__():初始化方法或构造方法,在用某个类创建对象时,会自动调用该类中的初始化方法。

  • __module__ :获取当前对象所属模块。无须在类内定义。

    __class__:获取当前对象所属类。无须在类内定义。

    class Foo:
        pass
    
    obj = Foo()
    
    print(obj.__class__)  # 打印:<class '__main__.Foo'>
    
  • __del__():析构方法,当对象在内存中被释放时,自动触发此方法。一般无须在类内定义。

    class Foo:
        def __del__(self):
            print("我被回收了!")
    
    obj = Foo()
    
    del obj  # 会自动调用__del__方法,打印:我被回收了!
    
  • __call__():在实例对象后面加括号进行调用,调用的就是__call__()方法。该方法需要自定义。

    class Foo:
        def __init__(self):
            print('__init__')
    
        def __call__(self):
            print('__call__')
    
    
    obj = Foo()     # 执行 __init__方法,打印:__init__
    obj()       # 执行 __call__方法,打印:__call__
    

    注意:对类进行调用,并不是单纯的调用__init__()方法这么简单。

  • __dict__:列出类或对象中的所有成员!无需自己定义。

  • __str__():在print(某个对象)时,会输出该方法的返回值。需要自己定义。

  • __getitem__:执行取值操作可迭代对象[下标或键]时,自动调用

    __setitem__:执行赋值操作可迭代对象[下标或键] = 值 时,自动调用

    __delitem__:执行删除操作del 可迭代对象[下标或键]时,自动调用

  • __iter__():定义了这个方法,并且让该方法的返回值是一个可迭代的对象,那么这个类的对象就是一个可迭代对象。

    class Foo:
    
        def __init__(self, sq):
            self.sq = sq
    
        def __iter__(self):
            return iter(self.sq)  # 返回可迭代对象
    
    obj = Foo([11,22,33,44])
    
    for i in obj:
        print(i)
    
  • __len__():使用内置的len()函数获取一个对象的长度,在后台,其实是去调用该对象的__len__()方法。

  • __repr__():和__str__()很像,两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串。

  • 在自定义的类中,重写以下方法,就能实现运算符的重载

    __add__: 加运算

    __sub__: 减运算

    __mul__: 乘运算

    __div__: 除运算

    __mod__: 求余运算

    __pow__: 幂运算

  • __author__:程序的作者信息,需要自己定义。

  • __slots__:限制实例属性的添加,添加不在该魔法属性内的实例属性时,会报错。

    class Foo:
        __slots__ = ("name", "age")
        pass
    
    foo = Foo()
    foo.gender = 'male'  # gender不在__slots__内,会报错
    

    下一篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花_城

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值