一、类的多种方法介绍
1、普通方法
普通方法就是上一篇文章介绍的类的方法,它的第一个参数必然是self,由实例对象调用的方法,用的是最多也是这种方法。
2、类方法
类方法,不同于普通方法,有一定的应用场景,具体有如下的特点:
① 类方法需要使用@classmethod装饰器装饰
② 类方法的第一个参数是cls,cls指示的是类对象自身
③ 通过类调用,会自动把类对象传入给cls,如果是对象调用,则会先找到所属的类,然后再传入给cls。
3、静态方法
静态方法,跟self和cls都没有关系,也可以理解为跟类和实例对象都没有关系,可以看做是一个放在类中的普通函数,使用的比较少,具体有如下的特点:
① 静态方法需要使用@staticmethod装饰器装饰
② 静态方法没有要求第一个参数是self或者cls,不会隐式的传入参数
③ 可以通过类或者实例对象调用,静态方法只是一个声明在类中的普通方法,由类这个名词空间管理,其他毫无作用。
class Person: name = 'Wu Ming' #定义一个普通方法,第一个参数必须是self def method(self): self.name = 'Wei xiaobao' print(self.name) #定义一个类方法,第一个参数必须是cls @classmethod def class_method(cls): cls.name = 'Zhang Wuji' print(cls.name) #定义一个静态方法 @staticmethod def static_method(): print(Person.name) >>> A = Person() #调用类的方法,把A这个实例对象传入给self >>> A.method() Wei xiaobao >>> Person.method() TypeError: method() missing 1 required positional argument: 'self' #调用类方法,把Persion这个类对象传入给cls >>> Person.class_method() Zhang Wuji >>> A.class_method() Zhang Wuji #调用类的静态方法,可以通过类或者实例对象调用静态方法 >>> Person.static_method() Zhang Wuji >>> A.static_method() Zhang Wuji
总结:
① 类的普通方法只能由类的实例对象调用,因为第一个参数self需要传入一个实例对象。
② 类的类方法和静态方法可以通过类或者实例对象调用,类方法的cls最终都只是接受一个类对象,静态方法不会自动隐式传入参数。
二、属性的访问控制
类的第一特性就是封装,为了更好的保护内部代码,大多数情况不会直接暴露类中定义的代码,而是通过提供的接口进行调用,而为了避免在类的外部直接访问甚至是直接修改类的属性,Python提供了两种方法来控制类属性的访问。
1、私有属性
在Python定义类属性的时候,使用双下划线“__”开头的属性,都是私有属性(私有变量和私有方法)。
class Person: def __init__(self, name, age): self.__name = name #私有变量 self.age = age self.__inner() def __inner(self): #私有方法 print(self.__name) print(self.age) >>> A = Person('jimmy',29) jimmy 29 #在外部直接调用私有属性,抛出异常 >>> A.__name AttributeError: 'Person' object has no attribute '__name' >>> A.__inner() AttributeError: 'Person' object has no attribute '__inner' #在外部直接调用普通属性,正常访问 >>> A.age 29
从上面的示例中可以看出,__name已经是私有属性,无法在外部访问了,而在内部可以正常使用。
那么私有属性的本质是什么?
看一下实例对象和类对象的属性字典,你就明白了,对,它就是把属性名称改名了而已,仅此而已,所以你在外部无法直接使用原来的属性名称进行访问了。
>>> A.__dict__ {'_Person__name': 'jimmy', 'age': 29} >>> Person.__dict__ '_Person__inner': <function __main__.Person.__inner(self)>,
既然只是改了个名字,但是终究还是可以通过外部访问,那么我们是否可以访问或者修改呢?
>>> A._Person__name 'jimmy' #通过实际属性名称修改__name变量的值 >>> A._Person__name = 'Jimmy' >>> A.__dict__ {'_Person__name': 'Jimmy', 'age': 29} #通过实际属性名称访问__inner方法 >>> A._Person__inner() jimmy 29
可以看到,我们仍然可以通过实际的属性名称去访问甚至是修改。
私有属性的总结:
① 在属性名称前面加上双下划线“__”。
② 私有属性在外部无法直接访问和修改。
③ 私有属性的本质只是修改了属性名字,在原来的属性名字前面加上“_classname”,可以通过实际的名称进行访问和修改。
④ 私有属性不具备强制性,可以绕过限制,但是一般不会这么做。
2、保护属性
在Python定义类属性的时候,使用一个下划线“_”开头的属性,就是保护属性。
保护属性的访问控制强度还没有私有属性的高,连私有属性都可以绕过访问和修改,保护属性就更不要说限制了,这里的保护更多的是一种约定,因为保护属性和普通属性一样,只是说我用了保护属性,你在外部就不要随便访问和修改了。
三、Python的方法重载
所谓方法重载,指的是同一个方法名,但是参数数量或者参数类型不一样,就是同一个方法的重载,在调用的时候,会根据传递的实参来自动调用相应的方法。
而Python中没有方法重载,Python也不需要方法重载,因为我们在学习函数定义的时候,已经知道函数的形参是非常灵活的,可以实现多种不同的传参方式,已经满足方法重载的需求。