简体   繁体   English

Python按文件夹模块导入

[英]Python imports by folder module

I have a directory structure: 我有一个目录结构:

example.py
templates/
    __init__.py
    a.py
    b.py

a.py and b.py have only one class, named the same as the file (because they are cheetah templates). a.pyb.py只有一个类,名称与文件相同(因为它们是猎豹模板)。 For purely style reasons, I want to be able to import and use these classes in example.py like so: 出于纯粹的样式原因,我希望能够在example.py导入和使用这些类,如下所示:

import templates

t = templates.a()

Right now I do that by having this in the template folder's __init__.py : 现在我通过在模板文件夹的__init__.py

__all__ = ["a", "b"]
from . import *

However, this seems pretty poor (and maybe superfluous), and doesn't even do what I want, as I have to use the classes like this: 然而,这似乎很差(也许是多余的),甚至没有做我想要的,因为我必须使用这样的类:

t = templates.a.a()

Thoughts? 思考?

To avoid repeating from <whatever> import * 25 times, you need a loop, such as: 为避免重复from <whatever> import * 25次,您需要一个循环,例如:

import sys

def _allimports(modnames)
  thismod = sys.modules[__name__]

  for modname in modnames:
    submodname = '%s.%s' % (thismod, modname)
    __import__(submodname)
    submod = sys.modules[submodname]
    thismod.__dict__.update(submod.__dict__)

_allimports('a b c d e'.split())  # or whatever

I'm putting the meaningful code in a function because (a) it's always best [[for performance and to avoid polluting the module's namespace]], (b) in this particular case it also avoids accidents (eg, some submodule might define a name thismod or modnames ... so it's important to keep those names that we're using in the loop local to the function, not module globals, so they can't be accidentally trampled;-). 我将有意义的代码放在一个函数中,因为(a)它始终是最好的[[用于性能并避免污染模块的命名空间]],(b)在这种特殊情况下它也避免了事故(例如,某些子模块可能定义了一个命名thismodmodnames ...所以将我们在循环中使用的那些名称保留在函数的本地, 而不是模块全局,这样它们就不会被意外踩踏;-)。

If you want to enforce the fact that a module named modname only has one class (or other global) with the same name, change the last statement of the loop to: 如果要强制执行名为modname的模块只有一个具有相同名称的类(或其他全局)的事实,请将循环的最后一个语句更改为:

    setattr(thismod, modname, getattr(submod, modname))

In your __init__.py : 在你的__init__.py

from a import *
from b import *

Now all of a 's contents will be in templates , as will all of b 's contents. 现在,所有的a的内容将在templates ,如将所有的b的内容。

I didn't even know you could have from . import * 我甚至都不知道你可以拥有from . import * from . import * . from . import * My python interpreter complains about such statements. 我的python解释器抱怨这样的声明。 Still, to your problem, you could do: 不过,对于你的问题,你可以这样做:

# __init__.py
from . import a, b
a = a.a
b = a.b

you can now use 你现在可以使用了

# example.py
import templates
t = templates.a()

other solution: 其他方案:

# __init__.py
from a import *
from b import *

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM