Python类account出现NameError: self未定义错误的原因是什么?
错误分析:NameError: name 'self' is not defined
首先来看你的account类代码:
class account(object): __duser_id = '' __duser_name ='' __duser_no = '' def __init__(self, default, entry_name, password, user_id='', user_name='', user_no=''): if type(default) != bool: raise Exception("Error 0x1: type(default) is boolean ") if default == False: self.__user_id = user_id self.__user_name = user_name self.__user_no = user_no else: self.__user_id = __duser_id self.__user_name = __duser_name self.__user_no = __duser_no self.__entry_name = entry_name self.__password = password def dset(self, duser_id=__duser_id, duser_name=__duser_name, duser_no=__duser_no): __duser_id = duser_id __duser_name = duser_name __duser_no = duser_no return (__duser_id, __duser_name, __duser_no) def dget(self): return (__duser_id, __duser_name, __duser_no) def set(self, user_name=self.__user_name, user_id=self.__user_id, user_no=self.__user_no, password=self.__password): self.__user_id = user_id self.__user_name = user_name self.__user_no = user_no self.__password = password return (self.__user_id, self.__user_name, self.__user_no, self.password) def get(self): return (self.__user_id, self.__user_name, self.__user_no, self.password) if __name__ == '__main__': gmail = account(default=True, entry_name='gmail', password='pass***') print(gmail.dget()) print(gmail.get())
运行后抛出的报错信息:
Traceback (most recent call last): File "interface.py", line 1, in <module> class account(object): File "interface.py", line 30, in account def set(self, user_name=self.__user_name, user_id=self.__user_id, user_no=self.__user_no, password=self.__password): NameError: name 'self' is not defined
错误具体内容
这个报错直白地告诉你:在定义set方法的默认参数时,Python找不到名为self的变量。
产生原因
这里的核心是Python方法默认参数的绑定时机:
- 方法的默认参数值是在类定义阶段就被计算并绑定的,而不是在你调用方法、创建实例之后。
- 当Python解析到
set方法的定义行时,account类还在初始化过程中,self(代表类的实例对象)根本还没被创建出来,自然找不到这个名字,直接抛出NameError。 - 退一步说,就算
self存在,默认参数绑定的是定义时的固定值,而不是实例当前的属性值——这也不符合你想用实例当前属性作为默认值的需求。
修复方案
要实现“用实例当前属性作为默认值”的效果,正确的做法是把默认参数设为None,然后在方法内部判断并赋值,同时还要修正self.password的笔误(应该是私有属性self.__password):
def set(self, user_name=None, user_id=None, user_no=None, password=None): # 只有当参数为None时,才使用实例当前的属性值 self.__user_id = user_id if user_id is not None else self.__user_id self.__user_name = user_name if user_name is not None else self.__user_name self.__user_no = user_no if user_no is not None else self.__user_no self.__password = password if password is not None else self.__password return (self.__user_id, self.__user_name, self.__user_no, self.__password) def get(self): return (self.__user_id, self.__user_name, self.__user_no, self.__password)
另外,你的类还有个隐藏问题:类级别的私有属性__duser_id等,在__init__、dset、dget方法里的引用方式不对,应该用account.__duser_id(类名访问),不然后续也会抛出NameError,这里顺便提一下。
内容的提问来源于stack exchange,提问作者user378625
相关产品推荐
相关产品推荐

