一、类对象及类属性
- 类对象: 类的定义执行后会生成一个类对象
- 类的属性: 类定义中的变量和类中定义的方法都是类的属性
- 类变量: 例如下面的 n a m e name name就是类的变量
- 类命名: 大驼峰方式,大写字母开头
class Person:
name = "leo"
def say(self):
print(self.name + ' say hello')
二、实例化
每次实例化后得到的实例,是完全不同的实例。Python类实例化后,会自动调用__init__ 方法进行初始化,这个方法第一个形参必须是self,指代当前对象。
class Person:
def __init__(self, name):
self.name = name
def say(self):
print(self.name + ' say hello')
def main():
# 这句话先构造一个全新实例,然后拿着name调用__init__方法,进行出厂配置。然后将配置完成的对象赋给变量leo
leo = Person('leo')
leo.say()
Person.say(leo) # 效果同leo.say()
if __name__ == '__main__':
main()
实例变量和类变量
class Person:
age = 20
def __init__(self, name):
self.name = name
def say(self):
print(self.name, "`s age is", self.age) # 直接用age访问不到
上面类中, a g e age age 是类变量,所有实例的 a g e age age属性被初始化为20,并且复制一份保存在自己的对象空间(此时成为实例变量),并且可以修改自己私有的该变量。而实例变量 n a m e name name就是每个实例私有的。
而类变量也可以直接修改,修改后再用该类实例化的对象的类属性就是修改后的类属性
Person.age = 100 # 修改类属性
leo = Person('leo')
leo.say() # 100
也可直接动态添加类属性,添加后原有的实例的若访问该属性,自己的私有空间找不到,回到类空间里找。
leo = Person('leo')
Person.height = 100 # 动态增加类属性
print(leo.height) # 100
类空间与对象空间 (类字典与对象字典)
Person.weight = 120 # 这只是在类空间中增加了weight
leo.weight = leo.weight + 10 # 执行完后,leo的对象空间中就多了weight属性
在 l e o . w e i g h t = l e o . w e i g h t + 10 leo.weight = leo.weight + 10 leo.weight=leo.weight+10 中,右边的 l e o . w e i g h t leo.weight leo.weight是访问了类空间中的 w e i g h t weight weight,然后在对象空间中创建一个 w e i g h t weight weight属性,接收类空间中的 w e i g h t weight weight加10后的值
三、特殊属性
- __ name __ :返回 类 名(字符串)
- __ class __ : 返回 对象 或 自定义类 的所属类
- __ dict __ : 返回 对象 或 当前类 的所有属性
leo = Person('leo')
print(leo.__class__) # 返回leo的所属类,<class '__main__.Person'>
print(Person.__class__) # <class 'type'>
print(leo.__dict__) # {'name': 'leo'}
print(Person.__dict__)
print(Person.__name__) # 返回字符串Person
实例属性的查找顺序: 指实例使用 “ . ” 访问属性,会先找自己的__dict__,如果没有就通过 __class__找到自己的类,再到类的 __dict__中找
私有属性
属性前以
双下划线
结尾就是私有属性
class Person(object):
def __init__(self, name):
self.__name = name
def main():
p = Person('leo')
print(p.__name)
if __name__ == '__main__':
main()
可以看到,我们访问不到以双下划线
结尾的属性__name
,我们需要加上前缀_class
即_Person
就可以访问:
print(p._Person__name) # leo
四、类方法和静态方法
class Person:
def method(self): # 实例方法,第一参数为实例对象
print('method')
@classmethod # 类方法,第一参数为类
def clsmtd(cls):
print(cls)
@staticmethod # 静态方法,没有第一参数,用的少
def stmtd():
print('static')
def main():
Person().method() # 实例调用实例方法
Person.method(Person()) # 效果同上
Person.clsmtd() # @classmethod装饰器会把Person类注入第一参数
Person().stmtd() # 实例对象调用静态方法
Person.stmtd() # 对象调用静态方法
Person().stmtd() # 实例对象调用类方法,装饰器通过__class__提取类传入类方法
类方法: 使用 @ c l a s s m e t h o d @classmethod @classmethod装饰的方法,有第一参数用于接收类 c l s cls cls, c l s cls cls标识符可以任意,但为了可读性,一般不建议修改。
静态方法: 使用 s t a t i c m e t h o d staticmethod staticmethod装饰器修饰的方法,不要求有第一参数。只是表明这个方法属于类空间。
总结:
- 类除了实例方法都可以调用,实例方法需要实例对象作为第一参数。
- 实例可以调用类中所有的方法(包括类方法、静态方法、实例方法),实例方法传入实例自身,静态方法和类方法需要找到实例的类