1. 类属性(类变量)和实例属性(实例变量)
在python中,类中的属性就是定义在类中的变量,简称成员变量;类中的行为就是定义在类中的方法,简称成员方法。成员变量又可分为类变量和实例变量,或者分为类属性和实例属性。成员方法又分为类方法和实例方法。类属性就是这个类所拥有的属性(变量),类属性被该类的所有实例对象所共有。对于公有的类属性,在类外可以通过类名或实例对象来访问。实例属性是该类的实例对象所拥有的,类对象无法拥有(通过类名无法访问实例属性)。
实例属性是定义在构造方法__init__
内部,而类属性是定义在类的内部,构造方法__init__
的外部。总而言之,类属性不属于任何一个实例对象,而是属于类本身。但所有的实例对象可以共享同一个类属性。当你修改类属性时,在所有的实例对象中都能看到类属性的变化。实例属性在类的每一个实例对象中独立存在,每个实例对象都有自己的实例属性,互不影响。
class Student:
school_name = "AAAAAA" # 公有类属性
__shcool_add = "XXXXXX" # 私有类属性
def __init__(self, name: str, age: int, id: str) -> None:
# stu_name、stu_age、stu_id都是实例属性
self.stu_name = name
self.stu_age = age
self.stu_id = id
stu = Student("zs",21,"0001") # 实例对象stu
# 访问类属性
print(Student.school_name) # 通过类名来访问公有类属性,输出:AAAAAA
print(stu.school_name) # 通过实例对象来访问公有类属性,输出:AAAAAA
# print(Student.__shcool_add) # 报错,因为在类外不能通过类名来访问私有类属性
# print(stu.__shcool_add) # 报错,因为在类外不能通过实例对象来访问私有类属性
# # 访问实例属性
print(stu.stu_name) # 通过实例对象来访问实例属性,输出:zs
# print(Student.stu_name) # 报错,实例属性是实例对象特有的,类对象无法访问
2. 类方法和实例方法
类方法是这个类所拥有的方法,需要用修饰器@classmethod
来标识其为类方法。对于类方法,第一个参数默认为cls
(当然也可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以cls
作为第一个参数的名字,就最好用cls
了),cls
表示类本身。能够通过实例对象和类对象(类名)去访问。
实例方法不需要任何修饰器,第一个参数默认为self
,表示实例对象本身。
class Student:
school_name = "AAAAAA" # 公有类属性
__shcool_add = "XXXXXX" # 私有类属性
def __init__(self, name: str, age: int, id: str) -> None:
# stu_name、stu_age、stu_id都是实例属性
self.stu_name = name
self.stu_age = age
self.stu_id = id
# 类方法
@classmethod
def get_school_info(cls) -> str:
return f"school_name = {cls.school_name}, school_add = {cls.__shcool_add}"
stu = Student("zs",21,"0001")
print(Student.get_school_info()) # 通过类名访问类方法
print(stu.get_school_info()) # 通过实例对象访问类方法
输出:
school_name = AAAAAA, school_add = XXXXXX
school_name = AAAAAA, school_add = XXXXXX
3. 静态方法
静态方法需要使用修饰器@staticmethod
来进行修饰,静态方法不需要额外定义参数。因此在静态方法中引用类属性,必须通过类对象(类名)来调用。
class Student:
school_name = "AAAAAA" # 公有类属性
__shcool_add = "XXXXXX" # 私有类属性
# 静态方法
@staticmethod
def get_school_info() -> str:
return f"school_name = {Student.school_name}, school_add = {Student.__shcool_add}"
stu = Student()
print(Student.get_school_info()) # 通过类名访问静态方法
print(stu.get_school_info()) # 通过实例对象访问静态方法
输出:
school_name = AAAAAA, school_add = XXXXXX
school_name = AAAAAA, school_add = XXXXXX