类属性&实例属性
类属性
类属性属于所有对象共有的,也就是所有对象都会使用同一个类属性,类属性定义在类的内部。
类属性可以直接通过类名调用,修改类属性则所有对象使用时就都会改变。
class Student:
name = 'chiruno'#类属性
height = 1.56
obj1 = Student()# 实例对象
obj2 = Student()
print(obj1.height)# 通过实例调用类属性
print(obj2.height)
Student.height = 1.60 # 通过类名修改类属性
print(obj1.height)
print(obj2.height)
'''
输出:
1.56
1.56
1.6
1.6
'''
实例属性
实例属性是对象所拥有的,每个对象会有不同的实例属性。
实例属性需要通过实例进行调用,在类内部也相同
class Student:
name = 'chiruno'
height = 1.56
def set_grade(self):
self.grade = 100# 类内部增加实例属性,self相当于java里的this
obj1 = Student()
obj2 = Student()
obj1.grade = 95# 增加实例属性
obj2.grade = 99
print(obj1.grade)
print(obj2.grade)
'''
输出:
95
99
'''
也可以通过__init__()方法为所有对象赋予统一的实例属性,init方法相当于构造方法,在实例初始化时会被调用
class Student:
name = 'chiruno'
height = 1.56
def __init__(self, grade: int):
self.grade = grade
两者的性质
类属性单独存在于一块内存区域,而所有实例则引用了他们
修改类属性应该通过类名调用修改,若通过实例修改,则会增加实例的属性
这是因为,当使用实例修改时会被认为是在实例内新增一个属性。
同时也说明了另一个问题,当类属性和实例属性有相同名字时,调用则会优先调用实例属性
class Student:
name = 'chiruno'
height = 1.56
obj1 = Student()
obj1.height = 111
print(Student.height)
print(obj1.height)
'''
输出:
1.56
111
'''
但是如果像是可变类型,可以通过实例对其进行修改,但是在使用=时依然会被认为是创建实例属性
class Student:
name = 'chiruno'
friends = []
obj1 = Student()
obj2 = Student()
obj1.friends.append('sakuya')
类方法
定义类方法需要在普通方法上面增加一个装饰器:
@classmethod
然后这个方法就会成为类方法,类方法存在于类的内存中,其所有实例都会拿到一个引用
通过类方法就可以修改和查看类属性
class Student:
name = 'chiruno'
friends = []
@classmethod
def set_name(cls, name):
cls.name = name
obj1 = Student()
print(id(obj1.set_name))
print(id(Student.set_name))
'''
输出:
2834049612872
2834049612872
'''
静态方法
类似于类方法,在方法上加装饰器:
@staticmethod
然后方法就会变为静态方法
静态方法同样可以通过类名修改类属性
class Student:
name = 'chiruno'
friends = []
@classmethod
def set_name(cls, name):
cls.name = name
@staticmethod
def add_friend(frd):
Student.friends.append(frd)
通过dir函数可以方便的查到某一区域内的所有属性
class Student:
name = 'chiruno'
friends = []
@classmethod
def set_name(cls, name):
cls.name = name
@staticmethod
def add_friend(frd):
Student.friends.append(frd)
print(dir(Student))