文章目录
前言
学完Java过后,对python中有了一些疑惑。Java中有static修饰的静态变量和静态方法这两个很用用的知识点,特别是在共享内存的操作上面。
Java静态变量和静态方法
Java多线程:在Java中使用多线程频繁使用静态变量(共享内存)
我就一直疑惑,Python中有没有类似的定义呢?因为真的好用采用Java中的那种风格写多线程。然后我就发现了Python中的这几个冷门知识点:
类变量(Java静态变量)
静态方法(Java静态方法)
类方法:这个是Python提供的更加灵活的方法
1 类变量(Java静态变量)
在 Python 中,类变量类似于 Java 的静态变量,属于类而不是对象。所有类的实例共享同一个类变量。
类变量的特点
- 共享:类变量是所有实例共享的。如果类变量的值被一个实例修改,所有其他实例看到的将是修改后的值。
- 定义位置:类变量在类体内定义,通常在方法之外。
- 访问方式:可以通过类名或实例名访问类变量。
class Student:
# python中类变量是所有实例共享的,就是java中的静态变量用static修饰的变量
teacher = "李华" # 类变量
def __init__(self,name,age,class_name):
self.name = name # 实例 成员变量
self.age = age
self.class_name = class_name
def modify_teacher(self,teacher):
# 修改类变量,需要通过类名.变量名的方式修改
# 如果直接使用self.teacher = teacher,那么只是修改了实例变量,而不是类变量(我们类变量的目的本来就是为了所有实例共享)
Student.teacher = teacher
s1 = Student("小明",18,"一班")
s1.modify_teacher("张三")
s2 = Student("小红",19,"一班")
print(s1.teacher) # 张三
print(s2.teacher) # 张三
这就是类变量,类变量通过类名访问,其属于这个类,其中一个类的实例修改了这个类变量,其余类的实例的这个变量也会一起变。这就和Java中的static修饰的变量是同样的效果。
并且这个知识点在多线程哪里会有大用。
2 Python中的静态方法(使用 @staticmethod 装饰器声明)
【注】:静态方法中不用传入self
- 访问方式:
外部可以通过类名或实例名访问类变量。
内部想要访问类属性和属于类的方法就必须通过类名. 访问
Python 中的静态方法使用 @staticmethod 装饰器声明。
- 静态方法只能访问静态变量(类变量)和静态方法。(必须通过 **类名.**来访问 )
- 静态方法不能访问类的实例变量或方法,因为它不依赖于具体的实例。
和Java里面静态方法的特性完全一致。
class Student:
teacher = "李老师" # 类变量
def __init__(self, name, age):
self.name = name # 实例变量
self.age = age # 实例变量
@staticmethod
def init_teacher(name):
# 定义一个静态方法,用来修改类变量teacher
Student.teacher = name
if __name__ == '__main__':
print(Student.teacher) # 李老师
Student.init_teacher("王老师")
print(Student.teacher) # 王老师
stu1 = Student("小明", 18)
stu2 = Student("小红", 19)
print(stu1.teacher) # 王老师
print(stu2.teacher) # 王老师
3 类方法(使用 @classmethod 装饰器声明)
【注】:类方法必须传入 cls 和self类似
- 访问方式:
外部可以通过类名或实例名访问类变量。
内部直接通过传进来的cls就可以访问类变量和类方法(属于整个类的),不包括实例属性和实例方法。
Python 还有一个与静态方法类似的概念,叫做类方法,使用 @classmethod 装饰器声明。类方法的第一个参数是 cls,表示类本身,而不是具体的对象实例。类方法能够访问类变量或调用类的其他方法。
其和静态方法作用上是没有任何区别的,只是在调用上有一些区别罢了
- 类方法只能访问静态变量(类变量)和静态方法(类方法)。(可以通过一个传入的 cls来访问)
- 类方法不能访问类的实例变量或方法,因为它不依赖于具体的实例。
class Student:
teacher = "李老师" # 类变量
def __init__(self, name, age):
self.name = name # 实例变量
self.age = age # 实例变量
@classmethod
def init_teacher(cls, name):
# 定义一个类方法,用来修改类变量teacher
# 必须传入cls参数,cls代表当前类,类似于self;可以通过cls访问类变量和类方法(包括静态方法);但是不能访问实例变量和实例方法
cls.teacher = name
if __name__ == '__main__':
print(Student.teacher) # 李老师
Student.init_teacher("王老师")
print(Student.teacher) # 王老师
s1 = Student("小明", 18)
s2 = Student("小红", 19)
s1.init_teacher("张老师")
print(s1.teacher) # 张老师
print(s2.teacher) # 张老师
4 静态方法和类方法的区别
实际作用上二者可以平替
区别:
- 静态方法不用传入cls,类方法必须传入cls
- 静态方法只能通过类名. 访问类变量和类方法;类方法可以通过传入的cls访问类变量和类方法
【注】:其实类方法是Python自己另外加的,Java没有。