【问题标题】:Python3:Passing function name as arguementPython3:将函数名作为参数传递
【发布时间】:2015-11-04 12:57:58
【问题描述】:

我正在学习 python oop 概念并偶然发现了我正在尝试编写的以下代码。有一个 Sort 类,它有不同的排序方法和一个通用函数 sort。

class Sort:
    def __init__(self, numlist):
        self.numlist = numlist

    def msort(self, beg, end, reverse=False): #merge sort
        if beg < end:
             mid = (beg + end)//2

             self.msort(beg, mid, reverse)
             self.msort(mid+1, end, reverse)
             self.__merge(beg, mid, end, reverse)


    def isort(self, beg, end, reverse=False): #insertion sort
        i = beg #initial index
        for key in numlist[beg+1:end+1]: #from beg+1 to end
            i = i+1 #current index in numlist
            j = i-1
            if reverse:
                while j >= beg and self.numlist[j] < key:
                    self.numlist[j+1] = self.numlist[j]
                    j = j-1
                self.numlist[j+1] = key
            else:
                while j >= beg and self.numlist[j] > key:
                    self.numlist[j+1] = self.numlist[j]
                    j = j-1
                self.numlist[j+1] = key


    def sort(self, beg, end, func=msort, reverse=False):
        print('Calling {0}()'.format(func))
        func(self, beg, end, reverse)

if __name__ == '__main__':
    numlist = [3, 4, 2, 5, 9, 7, 1, 6]
    s = Sort(numlist)
    s.sort(0, len(numlist)-1, func=isort, reverse=False)
    print(s.numlist, end='')

我有以下问题 - 1. 在 main 中,如果我只调用 s.sort(0, len(numlist)-1, reverse=False) 它会正确调用 msort 并给出结果,但如果我调用 s.sort(0, len(numlist)- 1, func=isort, reverse=False) 它给出以下错误 -

Traceback(最近一次调用最后一次):文件“Sort.py”,第 76 行,在 s.sort(0, len(numlist)-1, func=isort, reverse=False) NameError: name 'isort' is not defined

我明白为什么它不起作用,但不明白为什么 msort 能正常工作。

  1. 如果我调用 s.sort(0, len(numlist)-1, func=s.isort, reverse=False) 然后我得到以下错误 -

调用 main.Sort 对象 0x031BF830>>() Traceback(最近一次调用最后):文件“Sort.py”, 第 76 行,在 s.sort(0, len(numlist)-1, func=s.isort, reverse=False) 文件“Sort.py”,第 71 行,排序中 func(self, beg, end, reverse) TypeError: isort() 接受 3 到 4 个位置参数,但给出了 5 个

无法理解这里发生了什么。我好像调用了isort但是为什么参数不匹配

  1. 在函数 sort() 中,我无法调用 self.func() 再次给出属性错误。这是使用自我的坏习惯吗?在调用其他函数但调用 func() 时不使用 self.func()?

请解释组织这个类和函数调用的pythonic方式。

【问题讨论】:

  • 确保复制你的代码,包括缩进——你的def msort行应该缩进4个空格到Sort类,否则你会得到一个IndentationError你尝试运行这个
  • 这是您的第一个问题;欢迎来到 Stackoverflow!

标签: python


【解决方案1】:

您的错误是 isort 是一个实例方法,这意味着它不存在于 Sort 类的范围之外。您可以在main 中使用Sort.isort 来引用它:

s.sort(0, len(numlist)-1, func=Sort.isort, reverse=False)

出现第二个错误的原因是s.isort 已经将self(其中selfs)添加到isort 的参数列表中。当您调用 func(self, ...) 时,您将再次添加 self,因此您总共得到 5 个参数。

【讨论】:

    【解决方案2】:

    msort 在类定义范围内解析,因此它知道它是Sort.msort

    要在定义类之外使用isort,您需要使用传递Sort.isort

    当你传递s.isort时,方法已经绑定到对象,所以你不能传递self作为第一个参数。

    【讨论】:

      【解决方案3】:

      您应该将行 func(self, beg, end, reverse) 更改为 func(beg, end, reverse)。 self 参数是自动传递的。我可以让它与 s.isort 一起使用。

      【讨论】:

      • 在这种情况下你需要self.func(beg, end, reverse),否则它会寻找全局范围的函数func
      • @Robert 它不会寻找全局的func
      • 我尝试使用 self.func(beg, end, reverse) 但无论我如何传递 func 值它都不起作用 -
      【解决方案4】:

      感谢您的回复。对我来说,很少有事情是清楚的。我还在上面的程序中发现了一个错误,即我正在使用的 isort 函数

      for key in numlist[beg+1:end+1]:

      实际上应该是

      for key in self.numlist[beg+1:end+1]:

      我将总结以下发现 - 1. 如果我在 ma​​in 中传递 func=Sort.isort,则调用 func(self, beg, end, reverse) 有效 2. 调用 func(beg, end, reverse) 有效 如果我在 ma​​in

      中传递 func=s.isort

      以上2点我都理解了。

      1. 如果我在 ma​​in 中传递 func=Sort.isort,则调用 func(beg, end, reverse) 不起作用。它给了我错误-

      Calling() Traceback(最近 最后调用):文件“Sort.py”,第 79 行,在 s1.sort(0, len(numlist)-1, func=Sort.isort, reverse=False) 文件“Sort.py”,第 72 行,排序中 func(beg, end, reverse) 文件“Sort.py”,第 55 行,在 isort for key in self.numlist[beg+1:end+1]: #from beg+1 to end AttributeError: 'int' object has no attribute 'numlist'

      我猜如果 self 不是第一个参数,那么默认情况下 'int' 对象在 isort 中传递。所以它作为 int 的 cribbing 没有属性 numlist。

      1. 无论我如何在 main 中传递 func,调用 self.func(beg, end, reverse) 都不会起作用。我在 ma​​in 中尝试了 func=Sort.isort 和 func=s.isort 但每次都出现相同的属性错误提示

      AttributeError: 'Sort' 对象没有属性 'func'

      谁能证实我的发现?

      【讨论】:

        猜你喜欢
        • 2022-10-06
        • 2016-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-23
        • 2011-05-11
        • 1970-01-01
        • 2012-09-10
        相关资源
        最近更新 更多