Найти - Пользователи
Полная версия: Атрибуты класса.
Начало » Python для новичков » Атрибуты класса.
1 2
Alexey_mne31
Доброго времени суток.
Есть 2 класса с однотипными атрибутами, допустим:
 class Weapon():
    def __init__(self, health = 0, attack = 0, defense = 0, vampirism = 0,
                 heal_power = 0):
        self.health = health
        self.attack = attack
        self.defense = defense
        self.vampirism = vampirism
        self.heal_power = heal_power
class Sword(Weapon):
    def __init__(self):
        super().__init__(health = 5, attack = 2)
class Warrior:
    maxhealth = 50
    name = 'warrior'
    def __init__(self, health = 50, attack = 5, defense = 0):
        self.health = health
        self.attack = attack
        self.defense = defense
        self.equipped_list = []

Хочу написать функцию в классе Warrior, которая будет менять атрибуты, если объект класса Warrior “одел” объект класса Weapon.
 def equip_weapon(self, weapon):
        if not isinstance(weapon, Weapon()):
            weapon = Weapon()
        self.equipped_list.append(weapon) #пока пишем вручную
        self.health += weapon.health
        self.attack += weapon.attack
        self.............
Вопрос: есть какой-то способ обратиться ко всем атрибутам по очереди, сравнить название атрибутов в классах и для одинаковых выполнить действие?
Спасибо.
P.S. Для понимания привожу то, что выдумал сам для решения, но ЭТО не работает
 def equip_weapon(self, weapon):
        if not isinstance(weapon, Weapon):
            weapon = Weapon()
        list2 = [a for a in dir(weapon) if not a.startswith('__')]
        for a in list2:
            if self.a and self.a != 0:
                self.a += weapon.a
        self.equipped_list.append(weapon)

Ошибка вот такая:
 Traceback (most recent call last):
  File "<pyshell#145>", line 1, in <module>
    a.equip_weapon(b)
  File "C:/Users/Леха/Desktop/Battle/another solution test.py", line 32, in equip_weapon
    if self.a and self.a != 0:
AttributeError: 'Warrior' object has no attribute 'a'
py.user.next
Может, тебе подучиться? А то ты такую ахинею пишешь и даже не понимаешь этого. Как бы тут даже нечего посоветовать. Ты вот там инстанциируешь объект класса Weapon, в то время как этот класс абстрактный и нужен только для наследования от него. Или там ты собрался из одного объекта лезть во внутренности другого объекта, нарушая базовый принцип, про который ты, видимо, даже не в курсе. То есть это вот твои познания в ООП на таком уровне. А познания питона тоже говорят о многом в виде вот этих моментов по исползованию dir() и пробелов в имени модуля питона. Ноль на ноль равно ноль в квадрате.
Alexey_mne31
py.user.next
Может, тебе подучиться? А то ты такую ахинею пишешь и даже не понимаешь этого. Как бы тут даже нечего посоветовать. Ты вот там инстанциируешь объект класса Weapon, в то время как этот класс абстрактный и нужен только для наследования от него. Или там ты собрался из одного объекта лезть во внутренности другого объекта, нарушая базовый принцип, про который ты, видимо, даже не в курсе. То есть это вот твои познания в ООП на таком уровне. А познания питона тоже говорят о многом в виде вот этих моментов по исползованию dir() и пробелов в имени модуля питона. Ноль на ноль равно ноль в квадрате.
Ну я думал, форум Python для новичков - как раз место для таких вот неучей.
Немного не понял твои вопросы.
Да, я инстанциирую объект класса Weapon, потому что он является родительским классом для множества подклассов, и переменная в функции equip_weapon должна быть одним из этих подклассов. Поэтому я проверяю на принадлежность к общему классу.
Да, признаю, ошибся в следующей строчке, исправил бы действие, одну буковку поменял бы с верхнего регистра в нижний.
 if not isinstance(weapon, Weapon):
            weapon = weapon()
И да, мне надо подучиться, но когда лезешь подучиваться, оказываешься в дебрях тысяч страниц, а у меня на это нет времени, поэтому учусь по ходу, на примерах.

Использование dir() и пробелов в имени модуля питона я как раз таки подсмотрел, подучиваясь, в интернете. И, кстати, как бы коряво это ни было (я сам это понимаю), это работает иногда…как увижу решение получше, заменю арсенал.

А посоветовать надо вот что. Используя self вот здесь
 for a in list2:
            if self.a and self.a != 0:
                self.a += weapon.a
я перехожу от локальной переменной “а” как атрибуту класса. Но само использование self превращает мою локальную переменную в атрибут, которого, понятного дела нету. Вот мне и надо понять, как совместить локальную переменную метода “а” (которая перебирает названия атрибутов и на определенной итерации цикла хранит, допустим “attack”) с названием атрибута класса.
Если есть другой способ, не корявый, подскажите, как сделать объединение атрибутов 2 классов, отталкиваясь от названия атрибута (warrior.health + weapon. health, warrior.attack + weapon.attack, и т.д.)
так, чтобы потом дописывать атрибуты в классах Warrior и Weapon (допустим, потом захочу добавить speed и regeneration) и не дописывать сам метод equip_item.
P.S. еще раз извиняюсь за невежество, но это ФОРУМ ДЛЯ НОВИЧКОВ…ДАЖЕ НЕ ЧАЙНИКОВ, НОВИЧКОВ БЛИН…
Rodegast
> оказываешься в дебрях тысяч страниц, а у меня на это нет времени

Куда ты спешишь?

> я перехожу от локальной переменной “а” как атрибуту класса

Что значит “перехожу”? Ты обращаешься к атрибуту который не существует и получаешь ошибку. Всё норм.

> Но само использование self превращает мою локальную переменную в атрибут

Нет, не превращает.

> Вот мне и надо понять, как совместить локальную переменную метода “а” (которая перебирает названия атрибутов и на определенной итерации цикла хранит, допустим “attack”) с названием атрибута класса.

Погугли hasattr, и у тебя нет атрибутов класса.

> как сделать объединение атрибутов 2 классов, отталкиваясь от названия атрибута

А вот этого делать вообще не нужно и что бы это понять нужно нормально учится, а не так как ты.
Alexey_mne31
Rodegast
> оказываешься в дебрях тысяч страниц, а у меня на это нет времениКуда ты спешишь? > я перехожу от локальной переменной “а” как атрибуту классаЧто значит “перехожу”? Ты обращаешься к атрибуту который не существует и получаешь ошибку. Всё норм.> Но само использование self превращает мою локальную переменную в атрибутНет, не превращает.> Вот мне и надо понять, как совместить локальную переменную метода “а” (которая перебирает названия атрибутов и на определенной итерации цикла хранит, допустим “attack”) с названием атрибута класса.Погугли hasattr, и у тебя нет атрибутов класса.> как сделать объединение атрибутов 2 классов, отталкиваясь от названия атрибутаА вот этого делать вообще не нужно и что бы это понять нужно нормально учится, а не так как ты.



 def equip_weapon(self, weapon):
        if not isinstance(weapon, Weapon):
            weapon = weapon()
        list1 = [getattr(weapon,a) for a in dir(weapon) if not a.startswith('__')]
        list2 = [a for a in dir(weapon) if not a.startswith('__')]
        list3 = dict(zip(list2, list1))
        for element in list3:
            if hasattr(self, element):
                setattr(self, element, getattr(self, element) + list3[element])
        self.equipped_list.append(weapon)

Вот решение, пусть и корявое, но работает!!!
Теперь как хочу могу атрибуты в классах добавлять удалять = метод будет работать, и его не надо менять

Выкусите. УХАХАХАХА!

А если серьезно, блин, будьте потолерантнее = все, кто учатся, тупят, поэтому они и учатся.

Rodegast
> как сделать объединение атрибутов 2 классов, отталкиваясь от названия атрибута

А вот этого делать вообще не нужно и что бы это понять нужно нормально учится, а не так как ты.

У меня есть задание:
 And finally, you should add an equip_weapon(weapon_name) method to all of the soldiers classes. It should equip the chosen soldier with the chosen weapon.
This method also should work for the units in the army. You should hold them in the list and use it like this:
my_army.units[0].equip_weapon(Sword()) - equip the first soldier with the sword.
Тут учись не учись: черным по белому: атрибуты объекта класса Weapon должны поменять атрибуты объекта класса Warrior
Вы сговорились, старички?
xam1816
Alexey_mne31
Выкусите. УХАХАХАХА!
может вот так нужно?
 class Weapon():
    def __init__(self, health = 0, attack = 0, defense = 0, vampirism = 0,
                 heal_power = 0):
        self.health = health
        self.attack = attack
        self.defense = defense
        self.vampirism = vampirism
        self.heal_power = heal_power
class Sword(Weapon):
    def __init__(self):
        super().__init__(health = 5, attack = 2)
class Warrior:
    maxhealth = 50
    name = 'warrior'
    def __init__(self, health = 50, attack = 5, defense = 0):
        self.health = health
        self.attack = attack
        self.defense = defense
        self.equipped_list = []
    def equip_weapon(self, weapon:Weapon):
        self.equipped_list.append(weapon)
        self.health += weapon.health
        self.attack += weapon.attack
        self.defense += weapon.defense
#
#
my_warrior = Warrior()
print('было:')
print(my_warrior.health, my_warrior.attack, my_warrior.defense)
my_warrior.equip_weapon(Sword())
print('стало:')
print(my_warrior.health, my_warrior.attack, my_warrior.defense)
print(my_warrior.equipped_list)

>>>
 было:
50 5 0
стало:
55 7 0
[<__main__.Sword object at 0x00000253005DEA48>]
Process finished with exit code 0
py.user.next
Alexey_mne31
У меня есть задание:
And finally, you should add an equip_weapon(weapon_name) method to all of the soldiers classes. It should equip the chosen soldier with the chosen weapon.
This method also should work for the units in the army. You should hold them in the list and use it like this:
my_army.units[0].equip_weapon(Sword()) - equip the first soldier with the sword.
Это задание на полиморфизм поведения.

Ну, другими словами, ты берёшь задания на интегралы, в то время как не знаешь таблицу умножения. Что в таком случае надо делать? Надо ли продолжать брать задания на интегралы? Можешь продолжать, конечно, только вот что это даст в результате? Я думаю, ничего не даст. И рассказать всем тоже, что ты умеешь решать интегралы, потому что решал их, ты тоже не сможешь. Дураков нет, чтобы верить на слово. Тебе дадут простейший интеграл решить и ты просто покажешь, что не знаешь, что это вообще такое.

Так что стратегия перепрофилирования у тебя никакая. Думаю, ты закончишь ничем.

Alexey_mne31
И да, мне надо подучиться, но когда лезешь подучиваться, оказываешься в дебрях тысяч страниц
Ну, ты имеешь в виду, что самообучиться ты не можешь и тебе нужен преподаватель, который составит программу обучение и всё такое? А-а-а… у тебя, походу, денег нет ещё на преподавателя. Тогда всё понятно.

Alexey_mne31
P.S. еще раз извиняюсь за невежество, но это ФОРУМ ДЛЯ НОВИЧКОВ…ДАЖЕ НЕ ЧАЙНИКОВ, НОВИЧКОВ БЛИН…
Новичков в питоне, в питоне! а не в программировании. Ты-то в программировании полный ноль. А программирование - это не питон, питон - это лишь инструмент для программирования. Это как карандаш. Карандаш - это не рисование, это просто инструмент для рисования. Взяв карандаш, ты не нарисуешь кошку, потому что ты просто не умеешь рисовать кошек вообще ничем. А карандаш тут вообще ни при чём. Ты его как ни бери, кошка от этого не нарисуется сама.

Вообще твой подход в стиле “я ничего не хочу читать, но всё хочу знать и уметь” и “а я тяп-ляп что-то сделаю и научусь так” наводит на мысли, что у тебя что-то с образованием не то. Видимо, тебе нужно не перепрофилироваться, а просто запрофилироваться.
Alexey_mne31
xam1816
спасибо. хоть один нормальный человек попробовал помочь

Да, так и нужно было.
Просто я попытался перебрать атрибуты циклом и сопоставить автоматически то, что ты сделал вручную ( и у меня, кстати, получилось.)


Спросил у старожилов, КАКОЙ есть общепринятый способ автоматического перебора и сопоставления атрибутов по названию? А они что-то разозлились на мой вопрос….приму к сведению, возможно, нет такого способа
xam1816
Alexey_mne31
КАКОЙ есть общепринятый способ автоматического перебора и сопоставления атрибутов по названию? А они что-то разозлились на мой вопрос
А если условия задачи поменяются на такие
 self.health *= weapon.health
self.attack -= weapon.attack
self.defense += weapon.defense

причем у разных классов может быть по-разному.Обрати внимание, что тебе нужно будет постоянно как-то адаптировать свое детище под изменяющиеся условия, вместо написания основного кода.
Alexey_mne31
xam1816

Я больше спорить не буду. Вот тебе кусок кода побольше, там 2 метода = мой и твой.
Попробуй моим одеть оба класса.
Потом своим одень ОБА класса и ты поймешь, зачем эти танцы с бубнами, если представишь, что подклассов Война у меня уже дохера, а оружжия еще больше.

 class Warrior:
    maxhealth = 50
    name = 'warrior'
    def __init__(self, health = 50, attack = 5, defense = 0):
        self.health = health
        self.attack = attack
        self.defense = defense
        self.equipped_list = []
    @property
    def is_alive(self):
        return self.health > 0
    @property
    def god_heal (self):
        self.health = self.maxhealth
    def hit(self, other):
        other.health -= other.damage(self.attack)
    def damage(self, attack):
        return max(attack - self.defense, 0)
    def equip_weapon(self, weapon):
        if not isinstance(weapon, Weapon):
            weapon = weapon()
        list1 = [getattr(weapon,a) for a in dir(weapon) if not a.startswith('__')]
        list2 = [a for a in dir(weapon) if not a.startswith('__')]
        list3 = dict(zip(list2, list1))
        for element in list3:
            if hasattr(self, element) and getattr(self,element) != 0:
                setattr(self, element, getattr(self, element) + list3[element])
        self.equipped_list.append(weapon)
    def equip_weapon2(self,weapon):
        self.equipped_list.append(weapon)
        self.health += weapon.health
        self.attack += weapon.attack
        self.defense += weapon.defense
        self.vampirism += weapon.vampirism
        self.heal_power += weapon.heal_power
class Vampire(Warrior):
    maxhealth = 40
    name = 'vampire'
    def __init__(self):
        super().__init__(health = 40, attack = 4)
        self.vampirism = 50
        
    def hit(self,other):
        other.health -= other.damage(self.attack)
        self.health = min(self.health + math.floor(self.vampirism
                          / 100 * other.damage(self.attack)), self.maxhealth)
class Weapon():
    def __init__(self, health = 0, attack = 0, defense = 0, vampirism = 0,
                 heal_power = 0):
        self.maxhealth = health
        self.health = health
        self.attack = attack
        self.defense = defense
        self.vampirism = vampirism
        self.heal_power = heal_power
class Catana(Weapon):
    def __init__(self):
        super().__init__(health = -20, attack = 6, defense = -5, vampirism = 50)

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB