-1

I am trying to call a function but it's not working. here is the code:

class Compagnie:
    def __init__(self, nom, actions, prix):
        self.nom = nom
        self.actions = actions
        self.prix = prix


    def setActions(self):
        print("Changer le nombre d'actions pour " + self.actions)

I did:

Compagnie.setActions(50)

and i'm getting this error : AttributeError: 'int' object has no attribute 'actions'

What am I doing wrong?

Chadi N
  • 439
  • 3
  • 13

4 Answers4

2

Classes can contain three types of methods:

  1. Instance methods, e.g.

    def imethod(self,...): ...
    

    These can be called only on an instance of a class, and can access class and instance attributes. The first parameter is traditionally called self and is automatically passed to the method when called on an instance:

    instance = Class()
    instance.imethod(...)
    
  2. Class methods, e.g.

    @classmethod
    def cmethod(cls,...): ...
    

    These can be called on the class itself or instances, but can only access class attributes. The first parameter is traditionally named cls and is automatically passed to the method when called on a class:

    Class.cmethod(...)
    instance.cmethod(...)  # works, but can't access instance attributes.
    
  3. Static methods, e.g.

    @staticmethod
    def smethod(...): ...
    

    These are functions related to the class, but can't access instance or class attributes, so they are not passed the class or instance object as the first parameter. They can be called on an instance or a class:

    instance = Class()
    Class.smethod(...)
    instance.smethod(...)
    

Example (Python 3.9):

class Demo:

    cvar = 1

    def __init__(self,ivar):
        self.ivar = ivar
    
    @classmethod
    def cmethod(cls):
        print(f'{cls.cvar=}')

    @staticmethod
    def smethod():
        print('static')

    def imethod(self):
        print(f'{self.cvar=} {self.ivar=}')

Demo.smethod()
Demo.cmethod()
instance = Demo(2)
instance.smethod()
instance.cmethod()
instance.imethod()

Output:

static
cls.cvar=1
static
cls.cvar=1
self.cvar=1 self.ivar=2

In your case, you defined an instance method, but didn't create an instance first, so the int parameter you tried to pass was passed as self, and internally tried to access actions on the integer 50. Create an instance first, and don't pass it any parameters. self will be automatically passed:

compagnie = Compagnie('nom','actions','prix')
compagnie.setActions()
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
1

The class definition defines Compagnie not Compagnies. Beyond that, invoking setActions requires an object so you first need to create:

compagnie = Compagnie("foo", "bar", 33.0)

compagnie.setActions(50)

However, this will fail because your definition of setActions does not take an argument. From the name, I assume it is meant to look something like:

    def setActions(self, actions):
        self.actions = actions
        print("Changer le nombre d'actions pour " + self.actions)
sfjac
  • 7,119
  • 5
  • 45
  • 69
  • 1
    Thanks for your answer, I just did that but it gave me error "TypeError: setActions() takes 1 positional argument but 2 were given" I don't understand why I got this error – Chadi N Dec 23 '20 at 17:57
  • Since there is no argument defined for ```setActions()``` other than self and it doesn't use any other arguments. calling it as ```compagnie.setActions()``` will work. Otherwise, you will have to change the definition of the function to add an argument to take in the int. – Aasim Sani Dec 23 '20 at 18:02
0

Your method setActions is not set up to take any arguments. "self" is a reference to the instance, and allows you to modify instance variables by using self. inside of that method. To fix this:

def setActions(self, val):
    self.actions = val
    print("Changer le nombre d'actions pour " + self.actions)
TrikStar42
  • 26
  • 3
0
def setActions(self):
    print("Changer le nombre d'actions pour " + self.actions)

this is an instance method. It means it accepts the instance as its first argument which is usually denoted by self. self allows methods to access the state of the instance. So when you called Compagnie.setActions(50), "50" is evaluated as an object. This is how it is evaluated by Python:

def setActions(50):
    print("Changer le nombre d'actions pour " + 50.actions)

since 50 has no property "actions", you get that error. Since it is instance method, it can be called by instance. Or if you want to call it by class, you should create an instance and pass it as an argument:

c=Compagnie(1,"'my_actions'","my_prix") # create an instance
Compagnie.setActions(c) # pass it as an arg
Yilmaz
  • 35,338
  • 10
  • 157
  • 202