【问题标题】:How to fix "name 'self' is not defined" error in python?如何修复python中的“名称'self'未定义”错误?
【发布时间】:2019-09-26 09:28:03
【问题描述】:

我正在尝试学习 python OOP,但遇到以下错误。

Exception has occurred: NameError
name 'self' is not defined
  File "/home/khalid/Desktop/MiniProject3/test1.py", line 27, in <module>
    login = first_class (self.Bank_Users.keys(), self.Bank_Users.values())
  File "/home/khalid/anaconda3/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/khalid/anaconda3/lib/python3.7/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/home/khalid/anaconda3/lib/python3.7/runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)

我已尝试搜索可能已解决的类似问题,但找不到解决此错误的方法。

class first_class(object):

    def __init__(self, UserName, Password, Bank_Users):
        self.UserName = UserName
        self.Password = Password
        self.Bank_Users = {"Aldo": "1234"}


    def login_or_exit(self):

        while True:
            print("Please Enter User Name")
            self.UserName = input(">> ")
            print("Please Enter Password")
            self.Password = input(">> ")

            if self.UserName in self.Bank_Users.keys() and self.Password in self.Bank_Users.values():
                print("Logging into", self.UserName)

            else:
                print("Unsuccesful!!")

login = first_class (self.Bank_Users.keys(), self.Bank_Users.values())
login.login_or_exit()

【问题讨论】:

  • 您只能在定义的上下文中使用self。在__init__ 和login_or_exist 函数中定义了self,但不在运行first_class(self.Bank_Users.keys(), ...) 的顶层。 self 在定义为参数或以其他方式绑定的特定上下文之外没有任何意义;我们无法告诉您如何修复它,除非我们知道您打算它是什么意思,并显示原本可以正常工作的代码。
  • 在您的__init__() 中硬编码Bank_Users 有什么意义,同时还采用该名称的参数(但随后忽略它)?
  • 顺便说一句,在 Python 中,将 类 命名为 CamelCase 并将成员命名为 lower_case 是一种很好的形式。请参阅python.org/dev/peps/pep-0008的样式指南
  • 你在课堂之外,在范围之外。

标签: python python-3.x oop self


【解决方案1】:

正确执行此操作可能如下所示:

class BankLoginSystem(object):
    def __init__(self, bank_users):
        self.bank_users = bank_users
        self.logged_in_user = None
    def login_or_exit(self):
        while True:
            print("Please Enter User Name")
            attempted_user = input(">> ")
            print("Please Enter Password")
            attempted_password = input(">> ")
            if attempted_password == self.bank_users.get(attempted_user):
                self.logged_in_user = attempted_user
                print("Success!!")
                return
            else:
                print("Unsuccesful!!")

# the user database is independent of the implementation
bank_users = { "Aldo": "1234" }

login = BankLoginSystem(bank_users)
login.login_or_exit()
print("Logged in user is: %s" % login.logged_in_user)

请注意,我们没有将用户名和密码作为对象的初始化参数——因为一个对象在其生命周期内可以有多个用户登录,这样做不会有道理。

同样,应该保持私有的东西(例如尝试的密码)我们不会存储在类成员变量中,而是严格保持为局部变量,这样它们就不会泄漏到范围之外。 (在真实系统中,您希望密码数据库具有加盐哈希,而不是真实密码,如果密码数据库本身泄漏,则包含损坏)。

顺便说一句,请注意,一般而言,将您的 I/O 逻辑与您的后端存储表示相结合是一个坏主意 - 通常,您希望将纯对象建模您的域与与用户发生的任何交互分开并且不同。

【讨论】:

  • 谢谢你。为什么在“login = BankLoginSystem(bank_users)”中使用“bank_users”?
  • 需要在某个地方获取数据,并且您不想在类定义中对其进行硬编码(如果您这样做了,则无法在不创建全新的类;而现在您可以用不同的用户集实例化 BankLoginSystem 5 次不同的时间以进行测试)。
  • 有道理,再次感谢!
猜你喜欢
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多