Почему необходимо использовать __new__ для инициализации объекта? - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь сделать игру на Python с использованием pygame, но я случайно отключил проверку ошибок в 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

1 Ответ

0 голосов
/ 26 октября 2018

Проблема здесь в том, что PyCharm не знает, какой должна быть настоящая подпись метода __init__, потому что файл распространяется как файл .pyd (например, .dll).Вы можете проверить это с помощью функции «Перейти к ... объявлению» (Ctrl + B) в pycharm на pg.Vector2 в вашем коде, а затем на pygame.math.Vector2 в pyame's __init__.py, пока не достигнете кода pygame.math.Здесь вы увидите следующее объявление:

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 не так.

Описана точно такая же проблемаздесь:

Почему некоторые встроенные функции Python имеют только pass?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...