0

我的编程方式反复出现问题,我需要帮助重组我做事的方式。

警告:这是一个很长的问题。我想尽可能多地包含有关错误性质的信息,以耗尽它的可能原因。

TL;DR 版本: import / includeorder 不允许我的主文件查看其他文件中定义的函数。如何改进我的编程风格以防止以后出现这种情况?

长版:我将以 Python 2.7 为例。假设我有一个文件main.py. 和另一个文件foo.py. main.py有我所有的主要代码,并且foo.py有一个包含main.py. 我所做的是我在同一个文件中定义类的对象,foo.py,就在类定义之后。我想如果我只是在那里实例化类,我可以简单地将该文件导入到任何其他需要它的文件中,并且该对象将已经存在以便立即使用。不必在某个时候实例化类,也不必担心在类实例化之前的某些东西在实际定义之前是否需要它。

问题是这通常有效,直到我使用另一个文件中定义的另一个类来执行此操作。解释器找不到第二类的对象,即使我将它导入一次main.py(因此这似乎不是来自多个导入的重复对象的问题)。因此,从本质上讲,main.py可以看到foo.py' 类对象,但不能看到 'bar.py对象。

我通常会设置一个项目,以便拥有一个主文件,以及定义数据以及该数据的使用和处理的其他文件。主文件调用一个函数或方法,该函数或方法通过调用整个程序中的其他函数和方法来实现。我只导入我正在调用其方法的类的数据,并在包含主文件中使用的数据的文件中,导入特定文件所需的所有其他内容。如果我要制作一个内存效率高的程序,这对我来说似乎是合乎逻辑的,但是我做事的方式显然有问题,因为它似乎永远无法与更大的程序一起使用。

这是代码中的一个简单示例(a. 我如何设置文件层次结构,(b. 我如何设置导入,以及(c. 我得到的错误类型的示例:

主要.py:

import foo
import bar

print foo.bar
print bat.bar

foo.py:

class Foo:
  def __init__(self):
    bar = 5

foo = Foo()

酒吧.py:

class Bar:
  def __init__(self):
    bar = "Hello"

bat = Bar()

这是我运行这个程序时遇到的错误:

Traceback (most recent call last):
  File "C:\Users\User\Desktop\main.py", line 4, in <module>
    print foo.bar
AttributeError: 'module' object has no attribute 'bar'

当我将 main.py 更改为此:

from foo import *
from bar import *

print foo.bar
print bat.bar

它得到一个不同的错误:

Traceback (most recent call last):
  File "C:\Users\User\Desktop\main.py", line 4, in <module>
    print foo.bar
AttributeError: Foo instance has no attribute 'bar'

我误解了如何使用进口或什么?因为如果我退后一步,main.py像这样:

from foo import *
from bar import *

foo = Foo()
bat = Bar()

print foo.bar
print bat.bar

在注释掉其他文件中类的实例化时,我得到了同样的错误:Foo instance has no attribute 'bar'.

为什么是这样?

这不仅仅发生在 Python 中,它也发生在 C++ 中,所以这就是为什么我建议这可能是我的编程风格是一个问题,而不是任何语法问题。

4

1 回答 1

3

import X在您当前的命名空间中创建一个X对象,其中包含该模块中定义的名称。这只会向您的命名空间添加一个名称。所以,在你的第一个例子中,

import foo
import bar

创建foo一个包含类Foo(可访问为foo.Foo)和对象foo(可访问为foo.foo)的模块对象;同样,bar有类bar.Bar和对象bar.batbar值得注意的是,因为在模块的顶层没有调用变量foofoo.bar所以不存在。

from X import YY将模块中匹配的所有内容X直接导入您的命名空间。这可能会在您当前的命名空间中创建一堆名称。所以,

from foo import *

创建名称Foo(引用类)和foo(引用 的实例Foo)。那么,在后一种情况下,foo将引用类的一个实例Foo,那么为什么不起作用foo.bar呢?

好吧,您实际上并没有定义foo.bar. 编码

def __init__(self):
    bar = 5

定义了一个用 value调用的局部变量。它不会将任何内容保存到类实例中!你必须写bar5

def __init__(self):
    self.bar = 5

完成这项工作。

如果您在使用 C++ 时遇到类似问题,我建议您放慢速度,一次只专注于一种语言。没有充分的理由尝试同时学习两者,因为从长远来看它只会让你感到困惑。在尝试学习另一种语言之前,先对一种语言有深入的了解(我个人推荐 Python)。

于 2013-09-11T03:43:44.677 回答