系列文章目录

一、私有成员

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

  • 含义:

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

  • 格式:

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

    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__():在实例后面加括号,会调用这个方法。需要定义。

    class Foo:
        def __init__(self):
            pass
    
        def __call__(self):
            print('__call__')
    
    
    obj = Foo()     # 执行 __init__
    obj()       # 执行 __call__
    
  • __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__内,会报错
    

    下一篇