【问题标题】:Trying to use the return value from one function in another but getting undefined variable instead试图在另一个函数中使用一个函数的返回值,但得到未定义的变量
【发布时间】:2021-04-10 13:21:16
【问题描述】:

我有这个代码:

class Pet(object):

    def __init__(self,name=""):
        self.name = name 
        self.kind = "Unknown"
        self.toys = []  
    def add_toys(self,toys):
        new_list = []
        for toy in self.toys:
            if toy not in new_list:
                new_list.append(toy)   
        return new_list
    def __str__(self):
        toys_list = add_toys(self,toys)  
        if self.toys == []:
            return "{} is a {} that has no toys".format(self.name,self.kind)
        else:
            return "{} is a {} that has the following toys: {}".format(self.name,self.kind,toys_list)     

在函数add_toys() 我有返回值new_list。 我想在函数__ str__ 中使用该返回值并将其定义为toys_list。 但是,当我写 toys_list = add_toys(self, toys) 时,它说:

add_toys 是一个未定义变量

【问题讨论】:

  • 我不完全确定您要达到的目标,但是对于您说“它说 add_toys 是一个未定义的变量。”的错误,我相信您需要self.add_toys
  • 这能回答你的问题吗? function name is undefined in python class

标签: python undefined-variable


【解决方案1】:

你的add_toys 方法不好,你没有使用toys 参数,它不应该返回任何东西,应该是这样的

class Pet:
    # __init__ is OK

    def add_toys(self, *toys):
        for toy in toys:
            if toy not in self.toys:
                self.toys.append(toy)

    def __str__(self):
        if not self.toys:
            return "{} is a {} that has no toys".format(self.name, self.kind)
        else:
            return "{} is a {} that has the following toys: {}".format(self.name, self.kind, self.toys)

使用喜欢

p = Pet("Foo")
p.add_toys("ball")
p.add_toys("plate", "frisbee")
print(p) # Foo is a Unknown that has the following toys: ['ball', 'plate', 'frisbee']

你可以直接使用set

class Pet:

    def __init__(self, name, kind="Unknown"):
        self.name = name
        self.kind = kind
        self.toys = set()

    def add_toys(self, *toys):
        self.toys.update(toys)

【讨论】:

    【解决方案2】:

    在 add_toys 中,您首先要从类级别变量中访问 Toys 变量,因此请删除该参数,第二个是 add_toys(self,toys) 语法不正确,您需要像 self.add_toys() 一样使用它

    class Pet(object):
        def __init__(self,name=""):
            self.name = name
            self.kind = "Unknown"
            self.toys = []
        
        def add_toys(self):
            new_list = []
            for toy in self.toys:
                if toy not in new_list:
                    new_list.append(toy)
            return new_list
        
        def __str__(self):
            toys_list = self.add_toys()
            if self.toys == []:
                return "{} is a {} that has no toys".format(self.name, self.kind)
            else:
                return "{} is a {} that has the following toys: {}".format(self.name, self.kind, toys_list)
    

    替代方案:

    class Pet(object):
        def __init__(self,name=""):
            self.name = name
            self.kind = "Unknown"
            self.toys = []
        
        def add_toys(self, toys):
            new_list = []
            for toy in toys:
                if toy not in new_list:
                    new_list.append(toy)
            return new_list
        
        def __str__(self):
            toys_list = self.add_toys(self.toys)
            if self.toys == []:
                return "{} is a {} that has no toys".format(self.name, self.kind)
            else:
                return "{} is a {} that has the following toys: {}".format(self.name, self.kind, toys_list)
    

    【讨论】:

      【解决方案3】:

      问题是未定义的函数。缺少引用 self(每个类成员、字段或方法都需要): toys_list = self.add_toys().

      重新考虑设计

      toys 集合为什么要管理两次? (a) 作为字段toys 可以有重复项, (b) 作为来自add_toys 的返回,它将隐藏重复项并确保唯一元素。

      您必须保持两者同步。它们的功能不同,应该应用于不同的用例。

      假设:独特的玩具

      我也会直接使用 set 作为字段 toys 的类型。因为这样您可以重用现有的数据结构,它保证唯一性您在add_toys 中明确实现。另外添加/更新功能方便修改集合。

      改进:字符串构建

      此外,您的字符串函数可以重构:

      def __str__(self):
          subject = "{} is a {}".format(self.name, self.kind)
          hasToys = "has no toys" if not self.toys else "has the following toys: {}".format(self.toys)
          return "{subject} that {hasToys}".format (subject, hasToys)
      

      它使用 三元运算符 代替 if 语句;直接引用(通过self!)新的set字段:self.toys 加上一个 3 步构建,以使 单次返回在最后成为清晰可见的预期。

      【讨论】:

        【解决方案4】:

        类方法不能直接调用,必须使用self调用。

        像这样..

        self.toys_list= self.add_toys(self, toys)
        

        【讨论】:

        • 我们不能在类中省略第一个参数selfself.add_toys( toys ) 吗?
        • 是的,我们可以省略第一个参数`self`,但我说的是方法名之前的self.,类下的任何方法或变量都不能直接调用,它会导致到未定义的错误。我们必须使用self. 来调用它,例如self.method_name()self.variable_name ..
        猜你喜欢
        • 2016-08-15
        • 1970-01-01
        • 2013-10-27
        • 2020-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多