Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';t在Python中使用外部函数更改类变量_Python_Python 3.x_Class_Variables - Fatal编程技术网

Can';t在Python中使用外部函数更改类变量

Can';t在Python中使用外部函数更改类变量,python,python-3.x,class,variables,Python,Python 3.x,Class,Variables,所以我做了一个游戏,我试图为玩家创建一个清单,我不能改变一个叫做“装备武器”的变量。我尝试了所有的方法,或者我得到了一个例外,或者当打印玩家的清单时,它显示了以前的武器。我也是初学者,所以如果我遗漏了什么,请告诉我 # Existing items # Need a funtion to create a random item with random stats and a random name within a certain range. yes_list = ["yes", "yea

所以我做了一个游戏,我试图为玩家创建一个清单,我不能改变一个叫做“装备武器”的变量。我尝试了所有的方法,或者我得到了一个例外,或者当打印玩家的清单时,它显示了以前的武器。我也是初学者,所以如果我遗漏了什么,请告诉我

# Existing items
# Need a funtion to create a random item with random stats and a random name within a certain range.

yes_list = ["yes", "yeah", "sure", "why not"]

add_attack = "Attack:"
add_defense = "Defense:"
add_HP = "HP added:"
rarity = "Rarity"

weapon_rusty_sword = {
    "Name:": "Rusty Sword",
    add_attack: 1,
    add_defense: 0,
    rarity: 1
}

weapon_sword_wooden = {
    "Name:": "Wooden Sword",
    add_attack: 1.5,
    add_defense: 0,
    rarity: 1
}

weapon_sword_iron = {
    "Name:": "Iron Sword",
    add_attack: 2,
    add_defense: 0,
    rarity: 2
}

armor_chest_rusty_mail = {
    "Name:": "Rusty Mail",
    add_attack: 0,
    add_defense: 1,
    rarity: 1
}

armor_legs_adventurers = {
    "Name:": "Adventurer's Leggings",
    add_attack: 0,
    add_defense: 1,
    rarity: 1
}

armor_legs_rash_leggings = {
    "Name:": "Rash Leggings",
    add_attack: 0,
    add_defense: 0.5,
    rarity: 1
}

armor_head_rusty_cap = {
    "Name:": "Rusty Cap",
    add_attack: 0,
    add_defense: 0.5,
    rarity: 1
}
potion_hp = {
    "Name:": "HP Potion,",
    add_HP: 4
}

class Person:

    #global equipped_weapon
    equipped_weapon = weapon_rusty_sword
    ui_equipped_weapon = {"Equipped Weapon: {}".format(weapon_rusty_sword): ""}

    equipped_armor = {
    "Head Protection:": {"Name": armor_head_rusty_cap["Name:"], "Defense": armor_head_rusty_cap[add_defense]},
    "Chest Protection:": {"Name": armor_chest_rusty_mail["Name:"], "Defense": armor_chest_rusty_mail[add_defense]},
    "Legs Protection:": {"Name": armor_legs_rash_leggings["Name:"], "Defense": armor_legs_rash_leggings[add_defense]},
    }

    ATTACK = 1 + equipped_weapon[add_attack]
    DEFENSE = 1
    HP = 20

    gold = 10

    potions = {"Potions: ": [potion_hp["Name:"]]}
    ui_gold = {"Gold: ": gold}

    def __init__(self):
        self.name = "Cavalex"

    inv = [
        equipped_armor,
        ui_equipped_weapon,
        potions,
        ui_gold
    ]

    def see_inventory(self):
        for element in self.inv:
            for k, v in element.items():
                if type(v) == list:
                    print(k, ' '.join(v))
                else:
                    print(k, v)

#    def equip_weapon(self, new_weapon_code):
#        global equipped_weapon
#        eq_val = input(
#            "Do you want to equip this weapon? ->( {} )<-\nNote that your current weapon ( {} )will be discarded.".format(new_weapon_code["Name:"], self.equipped_weapon["Name:"]))
#        if eq_val.lower() in yes_list:
#            #del self.equipped_weapon
#            self.equipped_weapon = new_weapon_code
#            print("The weapon you had was discarded.")
#        else:
#            print("The new weapon was discarded.")





# See total amount of defense.
def defense_points():
    return sum(value["Defense"] for key, value in player.equipped_armor.items())


def add_gold(amount):
    player.gold += amount

# Adding to inventory
def new_potion_to_inv(potion):
    player.potions["Potions: "].append(potion["Name:"])


def equipp_weapon(new_weapon_code):
    # global player.equipped_weapon
    eq_val = input(
        "Do you want to equip this weapon? ->( {} )<-\nNote that your current weapon ( {} )will be discarded.".format(
            new_weapon_code["Name:"], player.equipped_weapon["Name:"]))
    if eq_val.lower() in yes_list:
        del player.equipped_weapon
        player.equipped_weapon = new_weapon_code
        print("The weapon you had was discarded.")
    else:
        print("The new weapon was discarded.")

player = Person()

# game loop
while True:
    print("Your name: ", player.name)
    player.see_inventory() # Can't put print this function, else will print "None" in the end.
    print("\nThis is your total armor defense: {}".format(defense_points()))
    print()
    new_potion_to_inv(potion_hp)
    player.see_inventory()
    print(player.ATTACK)
    print()
    print("Now we are changing your weapon.")
    equipp_weapon(weapon_sword_iron)
    print()
    print(player.ATTACK)
    player.see_inventory()



    break
#现有项目
#需要一个函数来创建一个随机项目,在一定范围内具有随机统计数据和随机名称。
yes_list=[“yes”,“yeah”,“sure”,“why not”]
添加\u attack=“攻击:”
添加_defence=“defence:”
add_HP=“HP已添加:”
稀有性=“稀有性”
武器生锈的剑={
“名字::“生锈的剑”,
添加攻击:1,
添加_防御:0,
稀有性:1
}
武器、剑、木={
“名字::“木剑”,
新增攻击:1.5,
添加_防御:0,
稀有性:1
}
武器、剑、铁={
“名字::”铁剑“,
添加攻击:2,
添加_防御:0,
稀有性:2
}
盔甲\u箱子\u生锈\u邮件={
“姓名::“生锈的邮件”,
添加攻击:0,
加上:1,,
稀有性:1
}
护甲·腿·冒险家={
“姓名::“冒险家绑腿”,
添加攻击:0,
加上:1,,
稀有性:1
}
护甲、护腿、皮疹、护腿={
“姓名::“皮疹绑腿”,
添加攻击:0,
添加_防御:0.5,
稀有性:1
}
盔甲\u头\u生锈\u帽={
“姓名::“生锈的帽子”,
添加攻击:0,
添加_防御:0.5,
稀有性:1
}
药水\u hp={
“名称::“HP药剂,”,
加上HP:4
}
班长:
#全球装备反坦克武器
装备的武器=武器生锈的剑
ui_装备的武器={“装备的武器:{}”。格式(武器生锈的剑):“”
装备装甲={
“头部防护:”:{“名称”:盔甲头锈帽[“名称:”],“防御”:盔甲头锈帽[添加防御],
“护胸:”:{“名称”:护甲护胸生锈邮件[“名称:”],“防御”:护甲护胸生锈邮件[添加防御],
“腿部防护:”:{“名称”:护甲、护腿、护腿[“名称:”],“防御”:护甲、护腿、护腿[添加防御],
}
攻击=1+装备武器[增加攻击]
防御=1
HP=20
黄金=10
药剂={“药剂::[potion_hp[“名称:”]}
ui_gold={“gold::gold}
定义初始化(自):
self.name=“Cavalex”
库存=[
装备装甲,
装备了反坦克武器,
药剂,
乌尤黄金
]
def见库存(自我):
对于self.inv中的元素:
对于元素.items()中的k,v:
如果类型(v)==列表:
打印(k),“连接(v))
其他:
印刷品(k,v)
#def装备武器(自身、新武器代码):
#全球装备反坦克武器
#eq_val=输入(

#“你想装备这个武器吗?”->({})({})问题是你把装备的武器设置成了类属性,而不是实例属性。
del instance.attribute
只删除实例属性,它甚至不查找类属性

如果目标只是更改实例,您可以完全删除
del
;下一行将添加(如果不存在实例属性,隐藏类属性)或替换(如果已经存在实例属性)实例的特定武器

如果目标是更改类,则需要更改作业以对类进行操作:

type(player).equipped_weapon = new_weapon_code
Player.equipped_weapon = new_weapon_code
或显式命名类:

type(player).equipped_weapon = new_weapon_code
Player.equipped_weapon = new_weapon_code
无论哪种方式,
del
都不是必需的;分配新值将替换旧值,以与
del
显式相同的方式隐式删除对旧值的引用。执行
del类型(玩家)是完全合法的.装备武器
del Player.装备武器
删除特定的类属性,但这是毫无意义的;无论需要什么行为,简单地分配给类或实例属性都将丢弃旧的引用

更新:如您所述,删除
del
可以防止异常,但您的输出(从
查看\u inventory
)永远不会改变。这是因为
查看库存
正在查看
玩家.inv
,它反过来包含了对
玩家.ui装备的武器
原始值的引用。问题是,
ui装备的武器
装备的武器
是基于同一默认武器初始化的,但它们没有同步相互之间;更改一个对另一个没有影响(因此,在类或实例上更改装备的武器不会影响库存,因此
请参见库存

实际上,这里的解决方案是创建一个健全的类。你的类属性没有一个是有意义的;它们都是逻辑上的实例属性,应该这样定义。在一些情况下,它们只是另一个属性的面向方便的转换;在这些情况下,它们根本不应该是属性,而应该是
property
s,whichh基于另一个属性动态地重新计算它们的值,以防止它们不同步

下面是一个非常快速的重写(未测试,可能有小的拼写错误),它将所有对齐的属性移动到实例,并将其余属性转换为只读属性,这些属性的值从另一个实例属性派生:

import copy

# Factored out to avoid repetition
def clean_armor(armor):
    return {k.rstrip(':'): v
            for k, v in armor.items() if k in {'Name:', 'Defense:'}}

class Person:
    DEFAULT_WEAPON = weapon_rusty_sword
    DEFAULT_ARMOR = {
        "Head Protection:": clean_armor(armor_head_rusty_cap),
        "Chest Protection:": clean_armor(armor_chest_rusty_mail),
        "Legs Protection:": clean_armor(armor_legs_rash_leggings),
    }

    def __init__(self, name="Cavalex",
                 equipped_weapon=DEFAULT_WEAPON, equipped_armor=DEFAULT_ARMOR,
                 base_attack=1, base_defense=1,
                 hp=20, gold=10,
                 potions=(potion_hp["Name:"],)):
        self.name = name
        # deepcopy is defensive (so changing defaults doesn't retroactively
        # alter existing instance); can be removed if you guarantee defaults
        # won't be changed, or you want changes to defaults to affect
        # Players still wielding default items
        self.equipped_weapon = copy.deepcopy(equipped_weapon)
        self.equipped_armor = copy.deepcopy(equipped_armor)
        self.base_attack = int(base_attack)
        self.base_defense = int(base_defense)
        self.HP = int(hp)
        self.gold = int(gold)
        # potions only used as dictionary, but it's silly to store it as one
        # Just store list of potion names in protected attribute,
        # property can construct the expected dict on demand
        self._potions = list(potions)

    @property
    def ATTACK(self):
        return self.base_attack + self.equipped_weapon[add_attack]

    @property
    def DEFENSE(self):
        return self.base_defense + sum(armor['Defense'] for armor in self.equipped_armor.values())

    @property
    def potions(self):
        return {"Potions: ": self._potions}

    @property
    def ui_gold(self):
        return {"Gold: ": self.gold}

    @property
    def ui_equipped_weapon(self):
        return {"Equipped Weapon: {}".format(self.equipped_weapon): ""}

    @property:
    def inv(self):
        return [
            self.equipped_armor,
            self.ui_equipped_weapon,
            self.potions,
            self.ui_gold,
        ]

    def see_inventory(self):
        for element in self.inv:
            for k, v in element.items():
                if isinstance(v, list):
                    print(k, ' '.join(v))
                else:
                    print(k, v)
这仍然有很多值得怀疑的选择(不一致的属性/属性命名;
dict
s中奇怪的键名,这些键名似乎是为了使显示更容易,但使所有非显示使用更烦人;对仅作为实例方法才有意义的事情使用顶级函数,等等),但我保留了这些怪癖,使其成为现有类的替代品(但是在实例上设置了所有每个玩家的属性,而不是类,并且所有派生属性都是通过
属性
s计算的,而不是静态设置的,因为独立的静态属性会增加基本属性和派生属性不同步的几率)

我保存