简体   繁体   English

为什么访问`self.BASE_DIR`会导致“AttributeError: 'str' object has no attribute 'BASE_DIR'”?

[英]Why does accessing `self.BASE_DIR` lead to “AttributeError: 'str' object has no attribute 'BASE_DIR'”?

Inside a python class the with open line gets:在 python 类中, with open line 得到:

Traceback (most recent call last):   
File "c:\Users\anonymous\Desktop\checker.py", line 54, in <module>
    print(main.check("fubk"))   
File "c:\Users\anonymous\Desktop\checker.py", line 13, in check
    with open(f"{self.BASE_DIR}\\wordlist.txt", "r") as words: 
AttributeError: 'str' object has no attribute 'BASE_DIR'
class main:
    BASE_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))

    def __init__(self, string, similarity: float = 0.76, BASE_DIR =  BASE_DIR):
        self.string = string
        self.similarity = similarity
        self.BASE_DIR = BASE_DIR
        print(self.DATADIR)

    def check(self):
        with open(f"{self.BASE_DIR}\\wordlist.txt", "r") as words:
            badwords = words.read().splitlines()

You are using classes incorrectly.您使用的类不正确。 I recommend going through the tutorials on classes (again, even if you already have), such as this one from the Python docs: A First Look at Classes .我建议阅读有关类的教程(同样,即使您已经拥有),例如 Python 文档中的教程: A First Look at Classes

How to Fix怎么修

Basically, you are making 2 mistakes:基本上,你犯了两个错误:

  1. Calling check on the main class directly, not on an instance of main直接在main类上调用check ,而不是在main实例
  2. Defining check without the correct parameters, but still passing "fubk" when calling it在没有正确参数的情况下定义check ,但在调用它时仍然传递"fubk"

1st, change check to be a proper instance method: 1、将check更改为正确的实例方法:

def check(self, word):
    print(word)
    with open(f"{self.BASE_DIR}\\wordlist.txt", "r") as words:
        badwords = words.read().splitlines()
    if word in badwords:
        ...

An instance method's 1st parameter should be the instance object itself ( self ).实例方法的第一个参数应该是实例对象本身( self )。 So if you want to pass some argument to your function, you need to add it to your function definition (ex. word ).因此,如果您想将一些参数传递给您的函数,您需要将其添加到您的函数定义中(例如word )。

2nd, you need to instantiate an object of main . 2,你需要实例化一个main对象。 Then call check on it.然后打电话check一下。

main_obj = main("string", similarity=0.5)
main_obj.check("fubk")

Here, the check method will receive the instance object as self (so it has access to all the self.string , self.BASE_DIR , etc. instance attributes) and the input "fubk" as word .在这里, check方法将接收实例对象作为self (因此它可以访问所有self.stringself.BASE_DIR等实例属性)和输入"fubk"作为word (I don't know what the string parameter is for). (我不知道string参数是干什么用的)。

What did the original error mean?原来的错误是什么意思?

Your original error:你原来的错误:

    print(main.check("fubk"))   
File "c:\Users\anonymous\Desktop\checker.py", line 13, in check
    with open(f"{self.BASE_DIR}\\wordlist.txt", "r") as words:
AttributeError: 'str' object has no attribute 'BASE_DIR'

is because check received "fubk" as self when it was called.是因为check在被调用时收到了"fubk"作为self You can see it if you printed out self .如果您打印self您可以看到它。

    def check(self):
        print(self)
        ...

main.check("fubk")

which would print out fubk .这将打印出fubk Your original code was trying to do:您的原始代码试图执行以下操作:

# {self.BASE_DIR}
"fubk".BASE_DIR

which leads to "'str' object has no attribute 'BASE_DIR'" .这导致"'str' object has no attribute 'BASE_DIR'"

Again, this error is avoidable if you instantiate your objects and define your instance methods properly.同样,如果您实例化对象并正确定义实例方法,则可以避免此错误。 In Python, self has a "special" meaning: see What is the purpose of the word 'self'?在 Python 中, self有一个“特殊”的含义:参见“self”这个词的目的是什么? . .

In addition, to avoid confusion, don't give your class variables and your instance variables the same name.另外,为了避免混淆,不要给你的变量和你的实例变量同名。 It can lead to some confusing behavior that you'll have to debug later (example: python class instance variables and class variables ).它可能会导致您稍后必须调试的一些令人困惑的行为(例如: python 类实例变量和类变量)。

class main:
    # class variable
    DEFAULT_BASE_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))

    # rename BASE_DIR function parameter
    def __init__(self, string, similarity: float = 0.76, custom_base_dir = None):
        ...
        # use parameter if provided or class default 
        self.BASE_DIR = custom_base_dir or DEFAULT_BASE_DIR

    def check(self):
        with open(f"{self.BASE_DIR}\\wordlist.txt", "r") as words:
            badwords = words.read().splitlines()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM