【问题标题】:Trying to call a function within class but it's not working [duplicate]试图在类中调用一个函数,但它不起作用[重复]
【发布时间】:2021-04-02 08:05:47
【问题描述】:

我正在尝试调用一个函数,但它不起作用。这是代码:

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)

我做到了:

Compagnie.setActions(50)

我收到了这个错误: AttributeError: 'int' object has no attribute 'actions'

我做错了什么?

【问题讨论】:

  • 你不能这样做,除非你先将方法定义为classmethod.Instantiate Companie对象。
  • 公司与公司?
  • @D.Seah 哦。我正在更新问题。
  • 您是否先实例化了一个实例?例如compagnie = Compagnie(["hello"], "world") 然后执行 compagnie.setActions()。顺便说一句,setActions 不带任何参数
  • 好的,知道了。你说得对!非常感谢!

标签: python


【解决方案1】:

类可以包含三种类型的方法:

  1. 实例方法,例如

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

    这些只能在类的实例上调用,并且可以访问类和实例属性。第一个参数传统上称为self,在实例上调用时会自动传递给方法:

    instance = Class()
    instance.imethod(...)
    
  2. 类方法,例如

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

    这些可以在类本身或实例上调用,但只能访问类属性。第一个参数传统上命名为cls,在类上调用时会自动传递给方法:

    Class.cmethod(...)
    instance.cmethod(...)  # works, but can't access instance attributes.
    
  3. 静态方法,例如

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

    这些是与类相关的函数,但不能访问实例或类属性,因此它们没有将类或实例对象作为第一个参数传递。它们可以在实例或类上调用:

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

示例(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()

输出:

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

在您的情况下,您定义了一个实例方法,但没有先创建实例,因此您尝试传递的int 参数作为self 传递,并在内部尝试访问整数上的actions 50。先创建一个实例,不要给它传递任何参数。 self 会自动传递:

compagnie = Compagnie('nom','actions','prix')
compagnie.setActions()

【讨论】:

    【解决方案2】:

    类定义定义Compagnie 而不是Compagnies。除此之外,调用setActions 需要一个对象,因此您首先需要创建:

    compagnie = Compagnie("foo", "bar", 33.0)
    
    compagnie.setActions(50)
    

    但是,这将失败,因为您对 setActions 的定义不带参数。从名字来看,我认为它看起来像:

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

    【讨论】:

    • 感谢您的回答,我只是这样做了,但它给了我错误“TypeError:setActions() 需要 1 个位置参数,但给出了 2 个”我不明白为什么会出现此错误
    • 因为除了 self 之外没有为 setActions() 定义任何参数并且它不使用任何其他参数。将其称为compagnie.setActions() 将起作用。否则,您将不得不更改函数的定义以添加要在 int 中获取的参数。
    【解决方案3】:

    您的方法 setActions 未设置为接受任何参数。 “self”是对实例的引用,并允许您使用 self 修改实例变量。在那个方法里面。要解决这个问题:

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

    【讨论】:

      【解决方案4】:
      def setActions(self):
          print("Changer le nombre d'actions pour " + self.actions)
      

      这是一个实例方法。这意味着它接受实例作为它的第一个参数,通常用self 表示。 self 允许方法访问实例的状态。因此,当您调用Compagnie.setActions(50) 时,“50”被评估为一个对象。这是 Python 评估它的方式:

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

      由于 50 没有属性“操作”,因此您会收到该错误。由于是实例方法,所以可以通过实例调用。或者如果你想按类调用它,你应该创建一个实例并将它作为参数传递:

      c=Compagnie(1,"'my_actions'","my_prix") # create an instance
      Compagnie.setActions(c) # pass it as an arg
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-27
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多