理解Python导入
我正在学习Django和Python,但有些地方我搞不懂。
(举个例子:'helloworld'是我的项目名称,它里面有一个叫'app'的应用。)
from helloworld.views import * # <<-- this works
from helloworld import views # <<-- this doesn't work
from helloworld.app import views # <<-- but this works. why?
看起来第2行和第3行几乎是一样的。为什么第2行不管用呢?
编辑 -- 添加了这两个文件的源代码。你可能会在Django书籍项目中看到这段代码(http://www.djangobook.com/en/2.0)
helloworld/views.py
from django.shortcuts import render_to_response
from django.http import HttpResponse, Http404
import datetime
def hello(request):
return HttpResponse("Hello world")
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response('current_datetime.html', locals())
def offset_datetime(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
next_time = datetime.datetime.now() + datetime.timedelta(hours=offset)
return render_to_response('offset_datetime.html', locals())
def display_meta(request):
values = request.META.items()
values.sort()
path = request.path
return render_to_response('metavalues.html', locals())
helloworld/app/views.py
from django.shortcuts import render_to_response
def search_form(request):
return render_to_response('search_form.html')
def search(request):
if 'q' in request.GET:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You searched for nothing.'
return render_to_response('search_results.html', locals())
3 个回答
正如sykora提到的,helloworld本身并不是一个包,所以第二种方法是行不通的。你需要有一个名为helloworld.py的文件,并且要正确设置。
几天前我问过关于导入的问题,这个链接可能对你有帮助:在Python中简单明了地设置导入路径?
from helloworld.views import * # <<-- this works
from helloworld import views # <<-- this doesn't work
from helloworld.app import views # <<-- but this works. why?
#2和#3是不一样的。
第二个是从包helloworld
中导入views
。而第三个是从包helloworld.app
中导入views
,这个helloworld.app
是helloworld
的一个子包。这意味着,views
是特定于你的django应用的,而不是你的项目。如果你有多个不同的应用,你该如何从每个应用中导入views
呢?你必须指定你想要导入的应用的名称,所以用到了helloworld.app
这样的写法。
在Python中,导入可以引入两种不同的东西:模块和对象。
import x
这行代码是导入一个叫做 x
的整个模块。
import x.y
这行代码是导入一个叫做 y
的模块,同时也导入了它的容器 x
。你可以用 x.y
来引用它。
不过,当你创建这个模块时,你是按照这样的目录结构来组织的:
x
__init__.py
y.py
当你在导入语句中添加内容时,你可以指定要从模块中提取的特定对象,并把它们放到全局命名空间中。
import x # the module as a whole
x.a # Must pick items out of the module
x.b
from x import a, b # two things lifted out of the module
a # items are global
b
如果helloworld是一个包(也就是一个目录,里面有一个 __init__.py
文件),通常它里面不会包含任何对象。
from x import y # isn't sensible
import x.y # importing a whole module.
有时候,你会在 __init__.py
文件中定义一些对象。
一般来说,使用 "from module import x" 可以从模块中选择特定的对象。
而使用 import module
则是导入整个模块。