Hướng dẫn python change class variable from outside - biến lớp thay đổi python từ bên ngoài

Vấn đề là bạn đã biến equipped_weapon một thuộc tính lớp, không phải là thuộc tính thể hiện. del instance.attribute Chỉ xóa các thuộc tính thể hiện, nó thậm chí không tìm kiếm các thuộc tính lớp.

Nếu mục tiêu chỉ là thay đổi thể hiện, bạn có thể xóa hoàn toàn del; Dòng tiếp theo sẽ thêm [nếu không có thuộc tính thể hiện tồn tại, theo dõi thuộc tính lớp] hoặc thay thế [nếu một thuộc tính thể hiện đã tồn tại] vũ khí cụ thể của phiên bản.

Nếu mục tiêu là thay đổi lớp, bạn cần thay đổi bài tập để vận hành trên lớp:

type[player].equipped_weapon = new_weapon_code

hoặc đặt tên rõ ràng cho lớp học:

Player.equipped_weapon = new_weapon_code

Dù bằng cách nào, del không cần thiết; Việc gán giá trị mới thay thế giá trị cũ, hoàn toàn bỏ tham chiếu đến giá trị cũ theo cùng một cách mà del không rõ ràng. Sẽ là hoàn toàn hợp pháp khi làm del type[player].equipped_weapon hoặc del Player.equipped_weapon để xóa thuộc tính lớp một cách cụ thể, nhưng nó vô nghĩa; Dù hành vi mong muốn, việc gán đơn giản cho lớp hoặc thuộc tính thể hiện sẽ loại bỏ tham chiếu cũ.

Cập nhật: Như bạn đã lưu ý, việc loại bỏ del ngăn chặn ngoại lệ, nhưng đầu ra của bạn [từ ____11] không bao giờ thay đổi. Đó là bởi vì

Player.equipped_weapon = new_weapon_code
1 đang xem xét
Player.equipped_weapon = new_weapon_code
3, từ đó chứa một tham chiếu đến giá trị ban đầu của
Player.equipped_weapon = new_weapon_code
4. Vấn đề là, trong khi
Player.equipped_weapon = new_weapon_code
5 và equipped_weapon được khởi tạo dựa trên cùng một vũ khí mặc định, chúng không được đồng bộ hóa với nhau; Thay đổi người này không có tác dụng đối với cái kia [và do đó thay đổi equipped_weapon, trên lớp hoặc thể hiện, không ảnh hưởng đến
Player.equipped_weapon = new_weapon_code
8, do đó
Player.equipped_weapon = new_weapon_code
1 không bao giờ thay đổi].
: As you noted, removing the del prevents the exception, but your output [from
Player.equipped_weapon = new_weapon_code
1] never changes. That's because
Player.equipped_weapon = new_weapon_code
1 is looking at
Player.equipped_weapon = new_weapon_code
3, which in turn contains a reference to the original value of
Player.equipped_weapon = new_weapon_code
4. Problem is, while
Player.equipped_weapon = new_weapon_code
5 and equipped_weapon are initialized based on the same default weapon, they're not synced to one another; changing one has no effect on the other [and therefore changing equipped_weapon, on the class or instance, doesn't affect
Player.equipped_weapon = new_weapon_code
8, so
Player.equipped_weapon = new_weapon_code
1 never changes].

Thực sự, giải pháp ở đây là tạo ra một lớp lành mạnh. Không có thuộc tính lớp nào của bạn có ý nghĩa; Tất cả chúng đều thuộc tính thể hiện về mặt logic và nên được xác định như vậy. Trong một vài trường hợp, chúng chỉ là các phép biến đổi hướng đến sự thuận tiện của một thuộc tính khác; Trong những trường hợp đó, chúng hoàn toàn không nên là thuộc tính, mà là các ____2020, điều này tự động tính toán giá trị của chúng dựa trên một thuộc tính khác, ngăn không cho chúng thoát khỏi đồng bộ hóa.

Dưới đây là một bản viết lỗi thực sự nhanh [không được kiểm tra, có thể có lỗi chính tả nhỏ] di chuyển tất cả các thuộc tính chính đáng của bạn sang thể hiện và chuyển đổi phần còn lại thành các thuộc tính chỉ đọc có được giá trị của chúng từ thuộc tính thể hiện khác:

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]

Điều này vẫn có rất nhiều lựa chọn đáng ngờ [đặt tên thuộc tính/thuộc tính không nhất quán; tên khóa kỳ lạ trong

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]
1 dường như đã được chọn để hiển thị dễ dàng hơn, nhưng làm cho tất cả các trò chơi không gây khó chịu hơn; sử dụng các chức năng cấp cao nhất cho những thứ Chỉ có ý nghĩa như các phương thức thể hiện, v.v.], nhưng tôi đã bảo tồn những điều đó để giữ cho nó thay thế cho lớp hiện tại của bạn [nhưng với tất cả các thuộc tính mỗi người chơi được đặt trên thể hiện, không phải lớp và tất cả các thuộc tính có nguồn gốc Thông qua các ____20 thay vì đặt tĩnh, vì các thuộc tính tĩnh độc lập làm tăng tỷ lệ cược của cơ sở và các thuộc tính dẫn xuất thoát khỏi đồng bộ hóa].

Tôi bảo tồn hành vi cho phép bạn tạo

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]
3 mà không cung cấp bất kỳ đối số nào, mặc dù
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]
4 thực sự nên là một đối số không tùy chọn [trừ khi "Cavalex" là một cái tên phổ biến mà bạn có thể giả định một cách an toàn nếu không phải tất cả người chơi có tên đó ].

Tôi nhận ra rằng có vẻ như tẻ nhạt khi đánh vần

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]
5 và xác định các ____2020 khi bạn có thể chỉ cần sao chép dữ liệu từ thuộc tính sang thuộc tính dẫn xuất, nhưng về mặt mã mà bạn thực sự có thể sử dụng một cách có ý nghĩa mà không có sự lặp lại cực đoan [và rủi ro đi kèm về lỗi chính tả và lỗi logic], hiểu hành vi của, v.v., đây là cách duy nhất có ý nghĩa; A

Lý do bạn tạo ra các lớp là để cho phép bạn tạo ra nhiều trường hợp của lớp với các thuộc tính khác nhau, nhưng các hành vi được chia sẻ; Làm cho lớp A gần như-singleton bằng cách sử dụng trạng thái cấp độ hoàn toàn khiến lớp trở nên vô nghĩa, ít nhất là ở Python nơi thiết kế ngôn ngữ đa hướng có nghĩa là mẫu singleton hiếm khi cần thiết, nếu sử dụng trạng thái cấp lớp được xác định tại thời điểm định nghĩa sẽ loại bỏ Lợi thế duy nhất của mẫu, trì hoãn việc khởi tạo singleton cho đến khi cần thiết].

Bạn có thể thay đổi biến lớp trong Python không?

Chúng ta nên cẩn thận khi thay đổi giá trị của một biến lớp.Nếu chúng ta cố gắng thay đổi biến lớp bằng cách sử dụng một đối tượng, biến thể hiện mới [hoặc không tĩnh] cho đối tượng cụ thể đó sẽ được tạo và biến này, các biến lớp này.Dưới đây là một chương trình Python để chứng minh điều tương tự.. If we try to change a class variable using an object, a new instance [or non-static] variable for that particular object is created and this variable shadows the class variables. Below is a Python program to demonstrate the same.

Làm cách nào để thay đổi giá trị của thuộc tính lớp trong Python?

Nhưng hãy cẩn thận, nếu bạn muốn thay đổi thuộc tính lớp, bạn phải làm điều đó với ký hiệu ClassName.AttributEname.Nếu không, bạn sẽ tạo một biến thể hiện mới.ClassName. AttributeName. Otherwise, you will create a new instance variable.

Bạn có thể thay đổi các biến lớp không?

Bất kỳ đối tượng nào cũng có thể thay đổi giá trị của biến lớp, nhưng các biến lớp cũng có thể được thao tác mà không tạo ra một thể hiện của lớp., but class variables can also be manipulated without creating an instance of the class.

Chức năng Python có thể sử dụng biến bên ngoài không?

Trong Python, một biến được khai báo bên ngoài hàm hoặc trong phạm vi toàn cầu được gọi là biến toàn cầu.Điều này có nghĩa là một biến toàn cầu có thể được truy cập bên trong hoặc bên ngoài hàm.a variable declared outside of the function or in global scope is known as a global variable. This means that a global variable can be accessed inside or outside of the function.

Bài Viết Liên Quan

Chủ Đề