创建依赖于另一个属性

时间:2016-06-05 14:54:42

标签: python-2.7 class properties pygame

我目前正在使用Pygame中的一个小型RPG来习惯面向对象的编码。

在研究如何自动更新属性时,我遇到了以下内容:

class P:

    def __init__(self,x):
        self.x = x

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, x):
        if x < 0:
            self.__x = 0
        elif x > 1000:
            self.__x = 1000
        else:
            self.__x = x

我尝试将其应用于我的代码,但是我收到以下错误:

  File "weapons.py", line 13, in __init__
    self.name = '{} {}'.format(ammo, self.raw_name)

TypeError: name() takes exactly 3 arguments (2 given)

我理解错误是什么,但我不知道如何解决它,因为我需要raw_name和ammo属性来自动更新我的Arrow实例的名称。

我的班级是这样的:

class Projectile(Item):
    def __init__(self, name, value, image, x, y, speed, dmg, dmg_modif, ammo):
        super(Projectile, self).__init__(name, value, image, x, y)
        self.dest = (self.rect[0],self.rect[1])
        self.speed = speed
        self.dmg_modif = dmg_modif
        self.dmg = dmg
        self.orientation = 0
        self.ammo = ammo

    @property
    def name(self):
        return self.___name  


    @name.setter
    def name(self, raw_name, ammo):
        if '{} {}'.format(raw_name,ammo) != self.___name:
            self.___name = '{} {}'.format(raw_name,ammo)

返回错误的子类是:

class Arrow(Projectile):
    def __init__(self, ammo): #name, value, image, x, y, dmg
        self.raw_name = 'Arrows'
        self.name = '{} {}'.format(ammo, self.raw_name)
        self.value = 5
        self.image = variables.quiver_img
        self.speed = 4
        self.dmg = 2
        self.dmg_modif = 1
        super(Arrow, self).__init__(self.name, self.value, self.image, 200, 150, self.speed, self.dmg, self.dmg_modif, ammo)

父类是Item和MySprite:

class Item(MySprite):

    def __init__(self, name, value, image, x, y):
        # Call the parent class (Sprite) constructor
        super(Item, self).__init__(image, x, y)

        self.name = name
        self.value = value 
        self.inv_pos = -1

class MySprite(pygame.sprite.Sprite):
    def __init__(self,image,x,y):

        # Call the parent class (Sprite) constructor
        super(MySprite, self).__init__()
        self.image = image
        self.rect = self.image.get_rect().move(x, y) #initial placement
        self.top_cp = (self.rect[0]+self.rect[2]/2,self.rect[1])
        self.bot_cp = (self.top_cp[0],self.rect[1]+self.rect[3])
        self.left_cp = (self.rect[0],self.rect[1]+self.rect[3]/2)
        self.right_cp = (self.left_cp[0]+self.rect[2],self.left_cp[1])
        self.center = self.rect.center
        self.pos = self.rect.topleft
        self.blit_order = 1
        self.level =  variables.current_level #Level(1)#level to which sprite belongs

欢迎任何帮助!

2 个答案:

答案 0 :(得分:0)

下次请提供minimal example

您的代码看起来有点复杂。好的,第一个问题是你不能将多个参数传递给setter。您既可以传递元组,也可以使用传统的setter方法def set_name(self, name, ammo):

另一个问题是您在设置之前使用___name属性,例如在Arrow s __init__方法的第二行。

私有属性应该有一个下划线而不是三个(这只是一个警告其他程序员的惯例)。如果您有两个或更多下划线,则名称为mangled

此外,我认为只有在新名称等于旧名称(有点无意义;))时才更改setter中的名称。你到底想要做什么?也许你根本不需要属性。

这是您的代码的固定(最小)版本:

import pygame


class MySprite(pygame.sprite.Sprite):

    def __init__(self):
        super(MySprite, self).__init__()


class Item(MySprite):

    def __init__(self, name):
        super(Item, self).__init__()
        self.name = name


class Projectile(Item):
    def __init__(self, name):
        super(Projectile, self).__init__(name)

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name + ' foo'


class Arrow(Projectile):

    def __init__(self):
        super(Arrow, self).__init__(name='Arrows')

arrow = Arrow()
print(arrow.name)
arrow.name = 'New name'
print(arrow.name)

答案 1 :(得分:0)

所以我最终设法解决了我的问题:

class Projectile(object):
    def __init__(self, raw_name, ammo):
        self.raw_name = raw_name
        self.name = self.raw_name
        self.ammo = ammo

    @property
    def ammo(self):
        return self._ammo

    @ammo.setter
    def ammo(self, ammo):
        self.name = str(ammo) + self.raw_name
        self._ammo = ammo


class Arrow(Projectile):

    def __init__(self):
        self.raw_name = ' Arrows'
        self.name = self.raw_name
        super(Arrow, self).__init__(self.raw_name, ammo
        = 10)

arrow = Arrow()
print arrow.ammo 
print arrow.name 
arrow.ammo = 15
print arrow.ammo 
print arrow.name 

给出:

>>>10
>>>10 Arrows
>>>15
>>>15 Arrows