Niezrozumiałe zachowanie podczas "kopiowania" zmiennych - niejawne rzutowanie float na int

0

Witam
Dopiero zaczynam swoją przygodę z Pythonem korzystając z książki "Python Crash Course".
Pracując nad jednym z książkowych projektów korzystający z Pygame, napotkałem na zachowanie którego nie rozumie. Otóż w pewnym miejscu kodu zmieniamy pozycję x obiektu ( zmienna typu int - self.rect.x) kopiując do niej wartość ze zmiennej typu float(self.x). Zakładał bym, że zmienna self.rect.x ( referencja ) zostanie przypisana do obiektu typu float. Niestety tak się nie dzieje i wygląda to na niejawne rzutowanie w w jakiś wymuszony sposób. Myślałem, że zmienna self.rect.x jest ustawiana przez "property" ze sprawdzaniem typów, ale jednak "property" nie tak działa - co można sprawdzić po ID zmiennych. Jakieś pomysły?

Problematyczne miejsce to : self.rect.x = self.x

import pygame

class Ship:
    """A class to represent the ship"""

    def __init__(self, ai_game) -> None:
        """Initalize the ship and set its starting position"""
        self.screen = ai_game.screen
        self.screen_rect = self.screen.get_rect()

        #load the ship image and get its rect.
        self.image = pygame.image.load("PythonCrashCourse\Part 2 - projects\AlienInvasion\images\ship.bmp")
        self.rect = self.image.get_rect()
        #start each new ship at bottom center of the screen
        self.rect.midbottom = self.screen_rect.midbottom
        # Movment speed
        self.settings = ai_game.settings
        #Ship position
        self.x = float(self.rect.x)
        # Movment flag
        self.moving_right = False
        self.moving_left = False

    def blitme(self):
        """Draw thevship at its current location"""
        self.screen.blit(self.image, self.rect)

    def update(self):
        """Update the ship`s position on the movemtnet flag."""
        if self.moving_right:
            self.x += self.settings.ship_speed
        if self.moving_left:
            self.x -= self.settings.ship_speed

        self.rect.x = self.x
        print(f"Value of self.rect.x is {self.rect.x}, float value is {self.x}")
        print(f"id of self.rect.x is {id(self.rect.x)}, id value is {id(self.x)}")

konsola:
screenshot-20220930181653.png

1

Na pierwszy rzut oka wygląda OK, sa dwa różne obiekty mające tę sama wartość.

3

W takich niejasnych sprawach warto zawsze spojrzeć do kodu źródłowego.
Ustawienie atrybutu w klasie Rect realizowane jest:

 def __setattr__(self, name, value):
        if name == 'top' or name == 'y':
            self._r.y = value

## ---
        elif name == 'left' or name == 'x':  ##  ustawianie X
            self._r.x = int(value)           ##  wartość konwertowana jest do typu int 
  .... 
0

Tak jak napisał @Robert Karpiński, upewnij się najpierw czy Twój self.rect faktycznie wspiera koordynaty float.

0
Robert Karpiński napisał(a):

W takich niejasnych sprawach warto zawsze spojrzeć do kodu źródłowego.
Ustawienie atrybutu w klasie Rect realizowane jest:

 def __setattr__(self, name, value):
        if name == 'top' or name == 'y':
            self._r.y = value

## ---
        elif name == 'left' or name == 'x':  ##  ustawianie X
            self._r.x = int(value)           ##  wartość konwertowana jest do typu int 
  .... 

Dziękuje za odpowiedź - to z pewnością wyjaśnia wszystko. Mam tylko pytanie - w jakim źródle znalazł Pan ten kawałek kodu? Gdy patrzę na paczkę Pygame która jet pobrana poprzez PIP install , to widzę tylko plik interfejsu rect.pyi, ale nie mogę znaleźć w tej paczce samej klasy (rect.py). Zakładam, że samo "rect" jest realizowane w C poprzez rect.c

1 użytkowników online, w tym zalogowanych: 0, gości: 1