导入 Python 类但不执行该类

7

我的问题是关于一个文件,它包含一个类,并且在这个类内部有一堆代码需要执行。

所以每当我导入该文件时,代码就会被执行,而不需要创建该类的对象!以下是示例:

文件X

class d:
    def __init__(self):
        print 'print this will NOT be printed'
    print "this will be printed"

文件 B

import x

输出结果为这将被打印,所以我的问题是如何跳过执行直到创建一个新对象?


2
如何跳过执行直到创建新对象 -- 为什么不像其他的那个一样放在__init__里呢? - mgilson
1
为什么不把第二个 print 放在 __init__ 方法中呢?我认为 __init__ 可能是你要找的,因为根据定义,代码是在对象创建时运行的。 - Emmett Butler
因为真实的类比示例要大得多,大约有350行,所以很难重新修改它。 - Hamoudaq
同意@mgilson和@EmmettJButler的观点。当Python导入一个模块时,它会执行模块级别的代码,包括构建类定义与类方法等。因此,当你导入X,并且class d的定义被构建(这样你就可以从B中调用它)时,它会执行类内部的代码。通常这意味着你将设置类级别的变量并准备将未绑定的方法附加到实例上,但在你的情况下,它意味着该语句将被打印出来。比我更熟悉Python的人可以纠正我/更好地陈述这一点 :) - RocketDonkey
发布了一篇答案,然后阅读了评论。 @RocketDonkey 是正确的。使该评论成为答案所缺少的唯一事项是“...将您的代码重构为方法”。 RD,如果您将其作为答案发布,我会给您点赞。 - khoxsey
5个回答

3
在Python中,您无法这样做。在Python中,每个类都是第一级对象,Python类也是一个对象,即使没有该类的实例,类属性也可以存在。如果您只想抑制print语句的输出,可以在导入时重定向print语句的输出或创建一个上下文,例如此第一答案提供的上下文,并手动使用__import__语句。

1

你的问题类似于:我有一个函数

def f():
    print(1)
    print(2)

我该如何让print(1)被执行,而不是print(2)?实际上没有简单的方法。你需要明白的是def __init__(self)也是一个语句。你的类由那个语句和print语句组成。没有简单的方法只执行其中一个。当然,如果你可以改变类的源代码,只需将print放在__init__中,这样它会在实例创建后被调用。

1

如果你只是想在导入期间抑制打印(或任何其他可执行语句),请将它们包含在顶层模块执行的检查中:

if __name__ == '__main__':
    print 'this will be printed'

这将防止在导入期间打印,但允许在交互式执行模块时进行打印。


它不起作用,我尝试创建一个对象,但它没有打印语句。 - Hamoudaq
为了让该行打印出来,我执行了:python -i x.py。为了抑制打印,我执行了:python -i b.py。请展示您尝试过的代码,并告诉我如何调用它。 - stleary
OP 想知道“如何在创建新对象之前跳过执行它”,而不取决于模块是否已导入。我自己直到现在才发现。 - martineau
错过了这个,那么许多其他人提出的将代码移动到__init__或类似位置的建议似乎是最好的解决方案。 - stleary

1

正如其他人指出的那样,第二个print语句正在执行,因为它是类声明的一系列语句之一 - 当导入包含它们的模块时,所有这些语句都会被执行,因为声明是其顶级代码的一部分,而不是嵌套在函数或方法中。

第一个print语句没有执行,因为它是方法定义的一部分,其语句直到调用该方法才执行 --- 不像类定义中的语句。通常,当使用类的名称创建类的实例时(例如您的类名为d),将间接调用类的__init __()方法。

因此,尽管与显示的字符串文本相矛盾,要使第二个print语句仅在创建类的实例时执行(就像第一个语句一样),您还需要将其作为同一方法的一部分(或由其调用)。换句话说,在这样做之后,当导入包含类的文件时,它们都不会执行,但在创建类的任何实例时都会执行。这是我的意思:

文件x.py

class d:
    def __init__(self):
        print 'print this will NOT be printed'  # not true
        print "this will be printed when object is created"

文件 b.py

import x  # no print statements execute
obj = d()  # both print statements will be executed now

0

同意 @mgilson 和 @EmmettJButler 的观点 - 这段代码最好放在 __init__ 中。当 Python 导入一个模块时,它会执行模块级别的代码,包括构建类定义和类方法等。因此,当你 import X 时,class d 的定义被构建(这样你就可以从 B 中调用它),并且它会执行类内部的代码。通常情况下,这意味着你将设置类级别的变量并准备将未绑定的方法附加到实例上,但在你的情况下,这意味着你的语句将被打印出来。

正如其他人建议的那样,重构代码可能是你最好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接