python引用其他文件提示找不到模块,Python:为什么导入的模块不能引用另一个导入的模块?...

main.py:

import subone

import subtwo

subone.py:

a = 'abc'

subtwo.py:

print subone.a

Running python main.py throws a NameError: name 'subone' is not defined. I expected it to print 'abc'.

Refactoring it to use from import and classes doesn't help:

main.py:

from subone import * # Only using from X import * for example purposes.

from subtwo import *

print 'from main.py:', a.out

subone.py:

class A:

out = 'def'

a = A()

subtwo.py:

# This throws NameError: name 'a' is not defined

print a.out

# This throws NameError: name 'A' is not defined

b = A()

print b.out

BUT it will print 'from main.py: def'. (It works when using import too.)

Why does it work this way? It seems like once subone is imported, it should be available to subtwo.

Is it because it's bad programming to have imported modules depend on each other without going through their 'parent' module? Is there another, standard way to do this?

Update:

I now understand that the first example will not work because the line print subone.a doesn't recognize the name subone, it not being in subtwo's namespace (even though it's in main.py's), and it is being called from within the module subtwo. This can be fixed by using import subone at the top of subtwo.py -- it will not re-load the module but will add it to subtwo's namespace so subtwo can use it.

But what about this:

main.py:

from subone import Nugget

from subtwo import Wrap

wrap = Wrap()

print wrap.nugget.gold

subone.py:

class Nugget:

gold = 'def'

subtwo.py:

class Wrap:

nugget = Nugget()

I would think that since Wrap and Nugget are both loaded directly into main's namespace, that they would use main's namespace and be able to reference each other, but it throws a NameError: name 'Nugget' is not defined. IS IT because Wrap is evaluated/checked from within subtwo's namespace BEFORE being loaded into main's namespace?

解决方案

If you modified your subtwo.py this way then it will work

import subone

print subone.a

When you do subone.a in subtwo.py, you are trying to access the namespace subone in subtwo.py and in the namespace "subone", there should be a attribute "a".

When you do - import subone in subtwo.py, then subone is added to the namespace and subone namespace has attribute a. so subone.a will work.

I would also suggest that you play with dir() to see how namespaces are being added.

In subtwo.py, you can do the following:

print dir()

import subone

print dir()

print subone.a

Similarly, try adding "print dir()" before and after your import statements and the idea should become clear to you.

"import x" adds 'x' to the current modules

namespace while "from x import * " will

add all the module level attributes

directly into current module namespace

So in your above first example of main.py, subone.py and subtwo.py, the namespace in main.py will contain 'subone' and 'subtwo' while subtwo.py will have an empty namespace and can not access subone.a.

[Edit: Some more explanations]

Consider following files:

main.py

print "Before importing subone : ", dir()

import subone

print "After importing subone and before importing subtwo: ", dir()

import subtwo

print "After importing subone and subtwo: ", dir()

subone.py

a = 'abc'

subtwo.py

print dir()

import subone

print "module level print: ", subone.a

print dir()

def printX():

print subone.a

And the output of running main.py:

Before importing subone : ['__builtins__', '__doc__', '__file__', '__name__', '__package__']

After importing subone and before importing subtwo: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone']

['__builtins__', '__doc__', '__file__', '__name__', '__package__']

module level print: abc

['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone']

After importing subone and subtwo: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone', 'subtwo']

Some Observations

You will notice that importing a module subtwo.py, the print statement is executed immediately.

So when subone and subtwo are imported in main.py, the namespace of main.py is augmented.

That does not mean that namespace of subtwo will be augmented. so "a" is available only in main.py via subone.a

When we do import subone in subtwo.py then the namespace of subtwo is augmented with subone and attribute a of module subone is available in subtow.py via subone.a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值