You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类方法未用self初始化的m1是哪类变量?为何访问报错

类方法内无self前缀变量的作用域规则与报错原因

首先明确Python面向对象编程中三类变量的边界规则:

  • 方法内部不带任何前缀直接赋值的变量:属于方法局部变量,仅在当前方法运行时的局部作用域内有效,方法执行结束后就会被回收,不会绑定到类或者实例对象上。
  • 赋值时带self.前缀的变量:属于实例变量,会绑定到当前创建的实例对象上,仅能通过实例对象访问,不同实例的同名实例变量互相独立、互不影响。
  • 直接定义在类体中、所有类方法外部的变量:属于类变量,会绑定到类本身,可以通过类名直接访问,所有类实例共享同一份类变量数据。

你的代码报错原理

你在__init__方法中写的m1=m1、m2=m2,本质是把方法接收到的入参m1、m2,赋值给了方法内部的同名局部变量。这个操作完全没有把m1、m2和Student类、或者你创建的s1、s2实例做任何绑定,方法执行完打印完m1+m2的结果后,这两个局部变量就会被销毁。

这种同名局部变量赋值是完全无意义的操作,既不会修改类属性,也不会给实例挂载属性,所以不管你执行print(Student.m1)还是print(s1.m1),都会因为找不到对应属性抛出AttributeError。

正确写法参考

如果要给实例绑定属性,必须加self.前缀:

class Student:
    def __init__(self,m1,m2):
        # 把入参绑定到当前实例的属性上
        self.m1 = m1
        self.m2 = m2
        print(self.m1 + self.m2)

s1 = Student(10,20) # 输出30
s2 = Student(20,30) # 输出50
print(s1.m1) # 正常访问实例属性,输出10
# 注意:此时执行print(Student.m1)依然会报错,因为m1是实例属性不是类属性

如果要定义可以通过类名直接访问的类变量,需要把变量定义在方法外部:

class Student:
    # 类变量,所有实例共享
    total_student = 0
    def __init__(self,m1,m2):
        self.m1 = m1
        self.m2 = m2
        Student.total_student += 1

s1 = Student(10,20)
s2 = Student(20,30)
print(Student.total_student) # 类名直接访问类变量,输出2
print(s1.total_student) # 实例也可以访问共享的类变量,输出2

内容的提问来源于stack exchange,提问作者arin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:06:31