-2

quick question in python let's say my class goes like this

class Enemy():
   def __init__(self, level):
      self.level = level
      self.damage = self.level + 5

the thing is that since the self.damage value is instantiated once it will not update when self.level is changed, how can I make it do just that? I tried searching online but I have no idea what this is called so I cannot find any help

Yikes
  • 7
  • 5
  • 1
    Make `damage` a method that returns `self.level + 5`. – Scott Hunter Sep 10 '21 at 18:00
  • 4
    you could use a `@property` to make a function that behaves like a property and allow for some more complicated behaviour – Macattack Sep 10 '21 at 18:00
  • @ScottHunter but wouldn't I have to call this method everytime I level up? – Yikes Sep 10 '21 at 18:03
  • @Macattack i'll check this out right now! – Yikes Sep 10 '21 at 18:03
  • No; you would call it every time you want to know the value of `damage`. – Scott Hunter Sep 10 '21 at 18:06
  • @ScottHunter by doing so do I need to remove the self.damage = self.level + 5 from the init method? because then how would i be able to print the value just by calling it like i would with self.level – Yikes Sep 10 '21 at 18:14
  • @Yikes That's what properties are for - Macattack's comment is good advice – Alan Sep 10 '21 at 18:17
  • @Alan Ok thank you i guess this is the answer to my question the, but it just seems overly complicated for something pretty simple that is what makes me hesitant – Yikes Sep 10 '21 at 18:18
  • @Yikes The property decorator is simple once you are used to it and gives a nice safe way to get or set attribute values. It's highly recommended you learn how it works. – Alan Sep 10 '21 at 18:20

3 Answers3

1

You can use properties. Maybe you know getter and setter methods from other programming languages. Properties are the Python equivalent of them. In this case, you only need a getter method.

class Enemy():
   def __init__(self, level):
      self.level = level

   @property
   def damage(self):
      return self.level + 5

The beauty is, you can still access damage as an attribute on your instance like enemy.damage, without having to explicitly call the method, it's done automatically.

ScientiaEtVeritas
  • 5,158
  • 4
  • 41
  • 59
0

This is a nice article about properties:
https://www.freecodecamp.org/news/python-property-decorator/

They allow you to control how attributes are accessed, which makes it easier to update them in the future if you decide a change in needed. For example, instead of being a flat +5, you can change the value or make it variable and anything that calls the attribute will not be affected.

Later you can add a way of manually setting the damage if you wanted to, through the use of @damage.setter.

class Enemy():
  '''This holds the data and functionality for enemies'''

  def __init__(self, level):
    self.level = level
    # Show the damage being set
    print(self.damage)

  @property
  def damage(self):
    return self.level + 5
Alan
  • 2,914
  • 2
  • 14
  • 26
0

In addition to using properties, you can also make damage a function rather than a variable:

def damage():
    return self.level + 5
La-comadreja
  • 5,627
  • 11
  • 36
  • 64