【问题标题】:Why is it necessary to use __new__ to initialize an object?为什么必须使用 __new__ 来初始化一个对象?
【发布时间】:2019-03-31 01:51:49
【问题描述】:

我正在尝试使用 pygame 在 Python 中制作游戏,但我不小心禁用了 PyCharm 中的错误检查。结果,这就是我尝试初始化Vector2的方式:

self.vel = pg.Vector2(0, 0)
self.acc = pg.Vector2(0, self.GRAVITY)

在我重新启用错误检查后,PyCharm 给了我一条错误消息,告诉我改用 pg.Vector2.__new__(0, 0)。在我这样做之后,错误消息消失了,代码工作了。

现在是实际问题:

虽然错误消息被禁用,但我写了很多像上面的例子一样的错误代码。奇怪的是,代码实际上运行良好。即使有一半的代码有错误,游戏也可以正常启动和运行。

有人可以向我解释为什么上面的例子有效,但为什么它被认为是不好的?

完整代码:

import pygame as pg
from game.settings import *


class Player(pg.sprite.Sprite):
    """
    I'm a docstring hurr durr
    """

    ACCELERATION = 60 / FPS  # dummy value
    FRICTION = 1  # dummy value
    GRAVITY = 1  # dummy value
    LIFE = 5

    def __init__(self, x, y, h, w):
        super().__init__()

        self.x = x  # x position
        self.y = y  # y position
        self.h = h  # height
        self.w = w  # width

        self.vel = pg.Vector2.__new__(0, 0)
        self.acc = pg.Vector2.__new__(0, self.GRAVITY)

        self.rect = pg.Rect(x, y, w, h)

        self.image = pg.Surface(w, h)
        self.image.fill(RED)
        # self.image = pg.image.load("../resources/player.*")

    def update(self):
        # key updates
        keys = pg.key.get_pressed()
        if keys[pg.K_LEFT]:
            self.acc.x -= self.a
        if keys[pg.K_RIGHT]:
            self.acc.x += self.a
        # test jumping function
        if keys[pg.K_SPACE]:
            self.vel.y = -20

        # friction
        self.acc.x -= self.vel.x * self.FRICTION

        # update vel and pos
        self.vel.x += self.acc.x
        self.x += self.vel.x

        self.vel.y += self.acc.y
        self.y += self.vel.y

【问题讨论】:

  • 我们能多看一点上下文吗?您发布的那两行代码在哪里?那是在__init__ 方法中吗?还是在__new__ 方法中?可以给我们minimal reproducible example吗?
  • @Aran-Fey 完成。
  • 我看不到任何此类错误(或警告)。
  • 在这种情况下明确使用__new__ 听起来是错误的。 PyCharms 警告信息到底是什么?你使用什么版本的 PyCharm(以及哪些插件)?
  • 意外参数可能的被调用者:Vector2(self: Vector2) Vector2.__new__(*args, **kwargs)

标签: python pygame pycharm


【解决方案1】:

这里的问题是 PyCharm 不知道__init__ 方法的真正签名应该是什么,因为该文件作为.pyd 文件(如.dll)分发。您可以通过在代码中的pg.Vector2 上使用pycharm 中的“转到...声明”(Ctrl+B) 函数,然后在pygame 的__init__.py 中使用pygame.math.Vector2 来验证这一点,直到您到达@987654327 的代码@。在这里你会看到这样的声明:

def __init__(self): # real signature unknown; restored from __doc__
    pass

还要注意math.py 文件顶部的注释:

# from C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\pygame\math.cp35-win_amd64.pyd
# by generator 1.145

PyCharm 正在尽最大努力尝试生成看起来像实际代码的东西,但这只是一种猜测。

简而言之,在这种情况下,你是对的,而 pycharm 是错的。

这里描述了完全相同类型的问题:

Why do some built-in Python functions only have pass?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多