【问题标题】:Is there a way to override a method on an existing (system) class in Python?有没有办法覆盖 Python 中现有(系统)类的方法?
【发布时间】:2020-08-29 16:45:29
【问题描述】:

我正在准备一个涉及排序的考试问题。我想禁止学生在他们的解决方案中使用list.sort()。出于这个原因,我正在考虑覆盖该方法(例如通过引发警告的方法)。有没有一种方法可以在 Python 3 中轻松完成?使用反射? (或另一种解决方案,使学生不能在他们的代码中使用list.sort()。)

【问题讨论】:

  • 即使您设法删除/替换了list.sort 阻止您的学生执行以下操作的原因:ast.literal_eval(subprocess.check_output([sys.executable, '-Ic', f'print(sorted({the_list!r}))']).decode())(希望他们不要阅读此聊天)。唯一可以确定的方法是编译您自己的 Python 版本。无论如何,我认为如果他们提出list.sort,他们应该得到充分的信任,因为这是最 Pythonic 的解决方案 :-) 如果你想教授低级算法,你也许应该使用低级语言。至少为了 Python 未来的用户群。
  • stackoverflow.com/questions/6738987/… 应该会有所帮助。如果您尝试设置list.sort = my_sort_func,通常会收到错误can't set attributes of built-in/extension type 'list',但似乎还有其他解决方案。
  • 有一个项目 (Forbidden Fruit) 允许您在 CPython 中对内置类型进行猴子补丁。显然有办法恢复这些猴子补丁,所以它不是 100% 安全的(+ 这不是全局更改,所以调用另一个子进程很容易回避)。
  • @a_guest 确实禁果模块看起来很有趣。
  • @a_guest 我们在这里谈论的是一年级学生。如果设法做到ast.literal_eval(subprocess.check_output([sys.executable, '-Ic', f'print(sorted({the_list!r}))']).decode()) 之类的事情,他们可能应该通过课程:-)

标签: python python-3.x class methods overriding


【解决方案1】:

最后我们选择了一位同事指出的这个解决方案,这里为了示例而进行了简化。来自forbiddenfruitcurse 函数允许您简单地覆盖现有函数,例如sort

from forbiddenfruit import curse
def f ( v ):
    print ( "Error" )
curse(list,"sort", f)
l = [5,4,3,1]
l.sort ()
print (l)

因此,在这段代码中,我们将sort 替换为一个打印错误的函数,学生不能再依赖传统的sort

【讨论】:

    【解决方案2】:

    当然可以,但据我所知,您必须让您的学生使用自定义列表类而不是标准类。 如果你想做的事情没问题,你可以这样做:

    import random
    
    
    class CustomList(list):
        def sort(self, *, key=..., reverse: bool = ...) -> None:
            raise PermissionError("You're not permitted to use the built-in sort function")
    
    
    if __name__ == '__main__':
        lst = CustomList()
        for _ in range(0, 10):
            lst.append(random.randint(0, 100))
    
        lst.sort()
    

    请注意,您的学生将无法使用此实现执行 lst = [5, 3, 7, 1, 9] 语法,因为这会调用默认的内置列表实现。

    【讨论】:

    • @a_guest 我强烈不同意您试图在您的信息中暗示的内容。作为一名计算机科学老师,我知道如果你为作业设置这样的条件,学生将(在大多数情况下)遵循这些规则。并且检查他们是否使用了 CustomList 类比他们使用排序函数要容易得多。
    • @Roäc 我真的希望该解决方案能够与lst = [3,7,1,5,9] 等标准列表一起使用,因为这是关于列表操作的问题。不允许 list.sort() 的原因是因为我想到的练习有一个使用 sort() 的非常短但效率非常低的解决方案。此外,该解决方案不会测试我想在本练习中评估的能力。
    • @Roäc 我并不是要暗示他们的意图是在练习中作弊。相反,这样的限制将使他们明确地意识到现有的解决方案以及不允许他们使用它的事实,即使它就在他们手中,这可能是(i.m.o.)令人沮丧的经历。如果我能想象一个使用list.sort 的解决方案非常简洁,我不想通过编写十倍以上的代码来解决它。使用 Python 意味着使用整个工具箱。限制部分内容会给语言带来错误的感觉。
    • @KimMens 我对这个练习很好奇,因为 Python 的排序算法非常高效。如果在这种情况下确实效率低下,为什么不挑战您的学生用更有效的解决方案来击败该解决方案呢? Python 提供了一些模块,您可以使用这些模块轻松地对代码进行基准测试,这样它们自然会被激励(并且被要求)提出与 list.sort 不同的东西。
    • @KimMens 好的,我明白了。您能否详细说明您希望他们解决的问题是什么?也许这可以帮助某人根据您的需要给您答案
    猜你喜欢
    • 1970-01-01
    • 2020-09-15
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 2010-09-06
    • 1970-01-01
    • 2010-10-15
    相关资源
    最近更新 更多