实例【对象】属性和类属性之间的区别?
- 定义的位置不同,类属性直接定义在类中,对象属性定义在构造函数中
- 访问方式不同,类属性使用类名直接访问,对象属性使用对象访问
- 在内存中出现的时机不同,类属性随着类的加载而出现,对象属性随着对象的创建而出现
- 优先级不同,对象属性的优先级高于类属性
class Person(object): #1.定义位置 #类属性直接定义在类中 name = "person" def __init__(self,name): #实例【对象】属性定义在构造函数中 self.name = name #2.访问方式和内存中出现的时机 #类名.属性 或者 对象.属性 #类属性随着类的加载而出现 print(Person.name) #person #对象属性随着对象的创建而出现 per = Person("jack") #3.优先级:实例对象高于类属性 print(per.name) #jack #删除对象属性,会调用和实例属性同名的类属性 del per.name print(per.name) #person
注意:在实际应用中,尽量避免类属性和实例属性重名的情况
类常用属性
__name__:通过类名访问,获取类名相关字符串,在使用对象访问的时候报错
__dict__:通过类名访问,获取该类的信息,包含类方法,类属性,静态方法,成员方法,返回的是一个字典
通过对象访问,获取的是该对象的信息,包含该对象的所有属性和值,返回的是一个字典
__base__:通过类名访问,查看当前类的所有父类【基类】
class Animal(object): pass class Tiger(Animal): age = 10 name = "abc" def haha(self): print("haha") @classmethod def show(cls): print("show") @staticmethod def check(): print("check") print(Tiger.__name__) #Tiger print(Tiger.name) #abc t = Tiger() print(Tiger.__dict__) print(t.__dict__) #{} print(Tiger.__base__) #<class '__main__.Animal'>
动态添加实例属性和方法 (动态添加属性和方法,动态添加成员方法,类方法和静态方法)
- 动态添加属性和方法:
from types import MethodType class Person(object): #限制可以动态添加属性 __slots__=("name","age","func") #1.动态添加属性 per = Person() per.name = "jack" #2.动态添加方法 def show(self): print("showing") #参数:需要被动添加的函数名,需要被添加的对象 per.func = MethodType(show,per) #指向函数的变量可以被当做函数调用 per.func() #showing
说明原理:动态添加属性,MethodType创建了函数,类似于在现有函数show的基础上生成了一个新的函数,赋值给了func
- 类方法:使用@classmethod装饰器修饰的方法被称为是类方法,类方法可以使用类名调用,也可以使用对象调用,但是一般使用类名调用类方法 类方法的特点:必须有一个参数,一般写为cls【class】,代表当前类;类方法属于整个类,并不是属于耨个对象,在类方法中禁止出现self,在类方法中,可以直接通过cls调用当前类的方法以及访问当前类的属性
- 静态方法:使用@staticmethod装饰器修饰的方法被称为是静态方法,静态方法可以使用类名调用,也可使用对象调用,但是,一般使用类名调用静态方法
#成员方法,类方法,静态方法 class Pig(object): #1.类属性 age = 5 def __init__(self,age): #2.实例属性 self.age = age #3.成员方法 #self代表的是当前类的实例【对象】 def func1(self): print("func----1111") #4.类方法 #cls代表的是当前类Pig @classmethod def func2(cls): print("func----2222") #5.在类方法的内部通过cls创建当前类的对象,并且可以调用当前类中成员方法 p = cls(10) p.func1() #优先访问的是实例属性 print(p.age) #6.静态方法 #参数:对参数没有任何限制 @staticmethod def fun3(): print("fun----3333") #7.调用 pig = Pig(9) #调用类方法 Pig.func2() #func----2222 func----1111 10 pig.func2() #func----2222 func----1111 10 #调用静态方法 Pig.fun3() #fun----3333 pig.fun3() #fun----3333 #8.继承 class SubClass(Pig): def __init__(self,age): super().__init__(age) def func1(self): print("子类----1111") @classmethod def func2(cls): print("子类----2222") @staticmethod def fun3(): print("子类----3333") s = SubClass(20) s.func1() #子类----1111 s.func2() #子类----2222 s.fun3() #子类----3333
总结:成员方法【实例方法】,类方法,静态方法之间的区别
- 写法上:
- 实例方法:第一个参数必须是实例对象,一般用self表示
- 静态方法:参数没有要求
- 类方法:第一个参数必须是当前类,一般使用cls表示
- 在继承中的相同点:子类可以继承父类中的未被私有化的实例方法,静态方法,类方法,如果三种方法都被重写,任然优先调用子类中的方法