Python .__class__.__name__ 适用于一个类,但不适用于另一个类

Kek*_*mPC 3 python class attributeerror

如果我被认为非常愚蠢,我很抱歉,我对 python 比较陌生,我不知道我在这里做错了什么。

我有两个班级,我尝试使用以下命令获取两个班级的班级名称

*class*.__class__.__name__
Run Code Online (Sandbox Code Playgroud)

现在,正如我所说,这适用于一个类,但不适用于另一个类。

这些是我的课程:

class fb():
    val = 300
    mult = 2.0
    shsym = pygame.image.load('img/dummy2.png')
    value = 50
class a():
    occ = 0
    shsym = pygame.image.load('img/it/a/shsym.png')
    plsym = pygame.image.load('img/it/a/plsym.png')
    value = 100
    hesyms = [pygame.image.load('img/a/hesym0',pygame.image.load('img/dummy.png'))]
    coord = [(50, 300),(30, 435),(310, 350)]
Run Code Online (Sandbox Code Playgroud)

里面的变量可能并不重要,但由于我无法找出问题所在,所以我只包含了整个内容。

然后我定义它们

fob = fb()
ita = a()
Run Code Online (Sandbox Code Playgroud)

然后我将变量设置为定义的类之一

itemselect = fob
Run Code Online (Sandbox Code Playgroud)

最后,我尝试检查类的名称并查看它是否以“f”开头(看看它是否是一组项目的一部分)

if not itemselect.__class__.__name__.startswith("f"):
Run Code Online (Sandbox Code Playgroud)

在那一行我收到错误消息

Traceback (most recent call last):
  File "D:\Programmieren\Cola Atsume\main.py", line 283, in <module>
     if not itemselect.__class__.__name__.startswith("f"):
AttributeError: class fa has no attribute '__class__'
Run Code Online (Sandbox Code Playgroud)

当 itemselect 为 ita 时,一切正常,但使用 fob 时则不然。我知道我可以用不同的方式来做这件事,而且我的整个班级系统并不是很传统,但如果不需要的话我真的不想改变它。

Jon*_*fer 5

注意:这是令人费解的 Python 2 内容。在 Python 3 中,情况有所不同,因为在 Python 3 中,每个类默认都是“新样式” 。新式类本身也是其元类的“简单”实例(通常这个元类是type)。这意味着 Python 3 中的类(以及继承自 的 Python 2 类object)实际上具有__class__属性(携带其元类)。现在不用担心元类。

\n\n

当错误发生时,itemselect是一个,而不是一个实例,这就是为什么它没有\xe2\x80\x99t有属性__class__

\n\n

你说:

\n\n
\n

然后我将变量设置为定义的类之一

\n
\n\n

确切地说,没有属性__class__。只有类的实例(也称为对象)才具有该属性:

\n\n
>>> class Foo:\n...     pass\n... \n>>> hasattr(Foo, "__class__")\nFalse\n>>> f = Foo()\n>>> hasattr(f, "__class__")\nTrue\n>>> f.__class__ is Foo\nTrue\n
Run Code Online (Sandbox Code Playgroud)\n\n

您需要强烈地区分类和对象,因为在大多数情况下,将它们混合在一起是错误的。

\n\n
\n\n

另外,你真的、真的、真的不应该这样做。您可以轻松地将其转换为基于 issubclass 的检查。

\n\n

创建一个名为的空类f

\n\n
class f:\n    pass\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在将所有名称开头的类作为基础f该类:

\n\n
class fb(f):\n    val = 300\n    mult = 2.0\n    shsym = pygame.image.load(\'img/dummy2.png\')\n    value = 50\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,不要进行令人讨厌的.startswith检查,而是使用issubclass

\n\n
if issubclass(itemselect, f):\n
Run Code Online (Sandbox Code Playgroud)\n\n

这比检查类名中的第一个字符已经干净得多。

\n\n
\n\n

另外,作为现在的初学者,你真的真的不应该使用 Python 2,现在你也没有\xe2\x80\x99t 有借口使用旧式类,因为你知道新式类存在。它将移植你的代码和你关于 Python 工作原理的思维模型更容易移植到 Python 3。

\n

  • 您没有显示产生问题的代码。当错误发生时,您不会将“ita”或“fob”分配给“itemselect”,因为在这种情况下它会起作用。您可以通过打印“ita.__class__.__name__”和“fob.__class__.__name__”来确认。在某些时候,您将“fb”分配给“itemselect”。``fb`` 是一个 **类**,而不是实例,因此没有 ``__class__`` 属性,因为它本身就是类。 (2认同)