繁体   English   中英

在Python中,我可以隐藏基类的成员吗?

[英]In Python, can I hide a base class's members?

我正在制作一个编程框架(基于Django),适用于编程经验有限的学生。 学生应该从我的基类继承(它们本身是从Django模型,表单和视图继承而来)。

我现在正在和一些学生一起测试这个问题,问题是当他们在IDE中编写代码时(大多数都是使用PyCharm),自动完成给了他们很多建议,因为有很多继承的方法和属性,90其中%与他们无关。

有没有办法隐藏这些继承的成员? 目前我主要考虑如何在自动完成中隐藏它们(在PyCharm和其他IDE中)。 它们可以(并且可能应该)在被调用时仍然可以工作,但是不会出现在自动完成的地方。

我尝试设置__dict__ ,但这并没有影响自动完成中显示的内容。 我的另一个想法是使用组合而不是继承,但我必须更详细地考虑这一点。

编辑 :此框架未在CS类中使用; 相反,学生将使用它来构建非CS域的应用程序。 因此,我的首要任务是尽可能保持简单,即使它不是一种“纯粹”的方法。 (尽管如此,我正在考虑这些论点,因为它们确实有价值。)

免责声明:以下方法不是很干净 (但这就是你要求的)。

现在,好消息是这个方法永远不会破坏你的Python 实际上,它只会影响IDE。

但请注意,PyCharm将来可能会变得更聪明,并且无论如何都可以自动完成工作。 不过,我认为这不会成为Jetbrains团队的首要任务!


开始了。

你所要做的就是混淆PyCharm。 PyCharm将无法可靠地跟踪使用__import__执行的__import__ ,因此我们将使用它来导入您的django模块(如果PyCharm没有导入您正在导入的模块,则无法知道您正在使用哪个类以及哪个类在自动完成窗口中显示的方法!)。

在以下示例中,我们假设:

  • _base.py是包含要扩展的类的django文件(以及要隐藏的方法)
  • base.py是包含您要为学生提供的课程的文件(您要显示的方法)
  • test.py是学生将要编写的文件

_base.py

这里没什么特别的

class DjangoBaseClass(object):
    def method_that_is_hidden(self):
        print "The hidden method is there!"

base.py

请注意导入

base = __import__("_base")  # This is equivalent to `import base`. Python understands it, but PyCharm doesn't.

class YourBaseClass(base.DjangoBaseClass):  # PyCharm doesn't know what class this is! No autocomplete.
    def method_that_shows(self):
        print "The method that shows is there!"

重要说明:在多级导入的情况下,语法略有不同。 例如,要继承自django.views.generic.base.View ,请执行以下操作:

base = __import('django.views.generic.base', fromlist=['View',])

class MyView(base.View):
    # Your stuff

请注意,如果PyCharm将来变得更聪明,你将不得不添加更多的间接(例如,而不是__import__('base') ,你可以使用__import__(''.join(['b', 'a', 's', 'e'])) 。但这会变得混乱。

test.py

这里没什么特别的

from base import YourBaseClass

class StudentClass(YourBaseClass):
    pass

if __name__ == "__main__":
    c = StudentClass()
    c.method_that_is_hidden()
    c.method_that_shows()

运行test.py脚本时,这些方法都有效:

$ python test.py
The hidden method is there!
The method that shows is there!

但是当您使用PyCharm时, method_that_is_hidden不会显示在自动完成中:

隐藏的方法没有显示


注意:我相信PyCharm现在具有在运行测试时跟随调用树的功能,因此如果您的学生使用PyCharm运行测试,PyCharm可能会接受这些方法的存在。 我想他们不会在课堂定义中表现出来,但是如果你的学生写c. ,他们可能会表明c. 你应该试一试,亲眼看看。

我建议你使用组合而不是继承。 然后设计类的接口并确定哪些方法可用。

我认为正确的解决方案是教你的学生python的命名约定 (并确保你的代码遵循它们)。 自动填充中的选项按字母顺序排列,字母表后面的'_'字符比'a'->'Z'字母更高,因此如果遵循命名约定,则公共API应首先位于自动完成列表中。 遵循该标准是他们无论如何都需要学习的一课,所以我不会试图将它隐藏起来。

现在我可以理解为什么你可能想要隐藏Django的公共API,但是考虑一下隐藏基类API而不是实际抽象它的其他结果:如果学生不知道方法名已被使用了怎么办?一个基类(因为它没有显示在自动完成中,或者你提供的文档中),决定命名一个他们自己的方法,并最终完全破坏一切,因为他们覆盖了一个方法而没有意识到它?

基本上,你试图隐藏学生实际上在课堂上的内容,而不是向他们传授他们需要知道的信息,而不是他们不应该做的事情。 这几乎总是导致简单地增加出错的可能性。 它还教他们完全依赖于IDE的功能; EX如果它不在自动完成中,它一定不存在!

我认为您需要查看您所关注的问题的根本原因,并尝试创建解决这些问题的课程,而不是找出解决这些问题的黑客,并可能教会您的学生重新编程。 学习如何正确阅读文档是一个真正的,非常重要的部分,是一个程序员。 不要试着让他们不必学习那一课。 地狱,没有学到那个教训是什么导致了Stack Exchange上99%的问题(尤其是因为任何原因在Python上)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM