Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在类定义尚未完成时,Python不允许我在类内使用方法_Python_Oop_Class_Methods_Python 2.6 - Fatal编程技术网

在类定义尚未完成时,Python不允许我在类内使用方法

在类定义尚未完成时,Python不允许我在类内使用方法,python,oop,class,methods,python-2.6,Python,Oop,Class,Methods,Python 2.6,我使用Python2.6作为批处理脚本的替代品。它将通过双击启动,因此用户将丢失/忽略所有到stdout的输出。所以,我决定添加日志记录,为了使事情变得简单,我为此编写了一个类。我的想法是,我可以在我的代码中的任何地方使用Logging.Logger,并且Logger将准备就绪 我希望目录中的旧日志文件不超过10个,所以我手动清除旧日志文件。我还没有通过API找到这样的功能,加上我有妄想症,我想记录所有的事情,事实上日志目录中有带有意外名称的文件 因此,下面是我在此类课程中的尝试,但我在尝试测试

我使用Python2.6作为批处理脚本的替代品。它将通过双击启动,因此用户将丢失/忽略所有到stdout的输出。所以,我决定添加日志记录,为了使事情变得简单,我为此编写了一个类。我的想法是,我可以在我的代码中的任何地方使用
Logging.Logger
,并且Logger将准备就绪

我希望目录中的旧日志文件不超过10个,所以我手动清除旧日志文件。我还没有通过API找到这样的功能,加上我有妄想症,我想记录所有的事情,事实上日志目录中有带有意外名称的文件

因此,下面是我在此类课程中的尝试,但我在尝试测试(运行)它时出错:


欢迎提出相关问题、风格建议和完整答案。谢谢

我认为它只需要记录。Python不像java那样进行名称空间解析:非限定名称是本地方法或全局方法。封闭范围(如类)不会自动搜索

关于Python如何处理名称的章节在语言参考手册的章节中。与此相关的位可能是:

类块中定义的名称范围仅限于类块;它不扩展到方法的代码块

与函数中定义的名称相比,函数向下继承(到方法本地函数和类中):

如果定义出现在功能块中,则范围将扩展到定义块中包含的任何块,除非包含的块为名称引入不同的绑定

更换线路

_assert(Logger, 'Logger does not exist yet! Why?')


这是因为您将
\u assert
定义为类的静态方法,静态方法必须被称为
ClassName.methodName
,即使您是从该类实例的方法调用它。

您得到该异常是因为您调用的是
\u assert()
,而不是
日志记录。\u assert()
。错误消息告诉您它正在模块的全局名称空间而不是类名称空间中查找
\u assert()
;要让它在后一种情况下查看,必须显式地指定它

当然,在本例中,您试图在类仍在定义时执行此操作,并且在类完成之前名称不可用,因此很难做到这一点

一个解决方案是取消缩进以下两行(我编辑了这两行以使用完全限定名),以便它们位于类定义之外;他们将在这之后被处决

Logger = Logging.__createLogger(Settings.LOGGING)
Logging.__clearOldLogs(Settings.LOGGING)
<>一个风格的建议将有助于:而不是用一堆静态方法来制作一个类,考虑在模块中使它们成为顶级函数。模块的用户(包括您自己)会发现更容易获得他们想要的功能。没有理由仅仅将类用作容器;模块本身就是这样一个容器

一个模块基本上是一个
*.py
文件(尽管您可以创建包含多个文件的模块,但现在就可以了)。当您执行
导入时
,您导入的是一个模块。在您的示例中,
tkMessageBox
logging
都是模块。因此,只需创建一个单独的文件(确保其名称不与现有Python模块名称冲突),将其保存在与主脚本相同的目录中,然后将其导入主脚本中。如果您将其命名为
mylogging.py
,那么您将
导入mylogging
,并将其中的函数访问为
mylogging.clearloldlogs()
或其他任何内容(类似于您现在将它们作为类来处理的方式)

Python中的“全局”名称并不是真正的全局名称,它们只是定义在其中的模块的全局名称。因此,模块是划分功能的好方法,特别是您预期在将来的脚本中重用的部分(如日志记录)。

一些评论

  • 不要使用双下划线,除非您完全确定必须使用双下划线以及为什么要使用双下划线

  • 要访问_assert方法,可以使用self调用它。类似于:self.\u assert(Logger,'Logger尚不存在!为什么?')在静态方法中,如您的示例中,使用类名:Logger.\u assert()。Python非常明确

  • 类仅在类定义的末尾创建。Python就是这样。但你的错误与此无关

  • 我不确定这段代码应该做什么:

    # Settings is a separate class (not dependent on this one).    
    Logger = __createLogger(Settings.LOGGING)
    __clearOldLogs(Settings.LOGGING)
    
    但是我想你应该把它放在
    \uuuu init\uuu
    方法中。在类构造期间,我没有立即看到任何需要访问该类的代码

  • \uu createLogger
    是一个奇怪的函数。这个类不是叫Logger吗?这不应该是Logger类的
    \uuuuu init\uuuu


  • 你能提供一个链接到某个更详细地解释这一点吗?@kindall,当我尝试使用:
    Loggin.\u assert()
    在Loggin类中,我得到以下错误:“NameError:name'Logging'未定义”。我需要找到一种方法来修改我的代码,以便它能够运行。您建议的单个更改没有做到这一点。@Hamish Grubijan:“向用户公开类和函数似乎很奇怪。”?为什么?S.洛特,我指的是类(有功能)和“孤独”函数。我担心的是,当我从x import*中执行
    操作时会产生污染,甚至有可能发生这种情况。@Hamish:我在回答中添加了更多的材料,以解决您提出的问题。另外,x import*
    中的
    被认为是不好的风格(出于各种原因,如果您感兴趣,人们会很乐意进入)。在Python中,您必须放弃的一件事是完全封装的思想;没有什么是真正的隐私。前导下划线仅仅是
    
    Logging._assert(Logger, 'Logger does not exist yet! Why?')
    
    Logger = Logging.__createLogger(Settings.LOGGING)
    Logging.__clearOldLogs(Settings.LOGGING)
    
    # Settings is a separate class (not dependent on this one).    
    Logger = __createLogger(Settings.LOGGING)
    __clearOldLogs(Settings.LOGGING)