2015-10-14 62 views
1

我有一个复杂的类层次结构,它涉及利用各种OS命令在自动化库中为它们提供统一的API。一些这些命令被经由基于静止接口经由CLI接口访问,其他人,并且在其中的类具有诸如这些包名:如何防止python中的冗余包和类名称

cmd.interface.cli.mgmt 
cmd.interface.cli.support 
cmd.interface.rest 

cmd.driver.cli.network_config 
cmd.result.cli.network_config 

cmd.driver.cli.stats 
cmd.result.cli.stats 

cmd.driver.rest.network_interface 
cmd.result.rest.network_interface 

等,等

有许多的这些,并且它们都是按逻辑进行分组的,并且具有基础类的层次结构,并且它们都包含与包路径中的最后一个文件名基本相同的名称的单个类定义。

即import语句,然后在“构造”的使用应该是这样的:

import cmd.driver.cli.network_config 
. 
. 
. 
config_driver = cmd.driver.cli.network_config.NetworkConfig(...) 

我发现这种类访问冗余是真的很烦人,而且它使代码看起来有种笨。

有没有一种很好的方法来消除这种命名冗余,同时保持模块分离和完好?

这里有一些事情我做不想这样做来解决这个问题:

1.

from cmd.driver.cli.network_config import NetworkConfig as CliDriverNetworkConfig 
from cmd.result.cli.network_config import NetworkConfig as CliResultNetworkConfig 
from cmd.driver.rest.network_config import NetworkConfig as RestDriverNetworkConfig 

(!啊)

我不想假装每一件事都有一个可爱的名字。我真的想在使用的时刻曝光的所有相关信息:

config_driver = cmd.driver.cli.network_config.NetworkConfig(...) 

(但我真的希望,这应该足以使代码可以理解的:

config_driver = cmd.driver.cli.NetworkConfig(...) 

  1. 在cmd/driver/cli/__ init中放置30个左右的类defs__py

(也难吃)

在Perl

,这会以这种方式来完成:

use Cmd::Driver::CLI::Network_Config; 
. 
. 
. 
my $config_driver = Cmd::Driver::CLI::Network_Config->new(...); 

有python中任何机制,可以让我以更简明呼吁这些类的构造函数不带包名称冗余,并且没有隐藏几个类似但可靠区分的类中的哪些类的重要细节完整名称被调用?

.............................................. ..

在后加上1小时加置评:

它发生,我认为是用perl也在做着同样的事情,这里的包是cmd ::驱动程序:: CLI :: Network_Config和类其中调用的方法是“新”。因此,在这种情况下,呼叫的外观更漂亮。

我想如果我命名模块cmd.driver.cli.NetworkConfig并放入一个名为'new'的包范围方法,它只是调用cmd.driver.cli.NetworkConfig.NetworkConfig(...)我会得到相同的的影响,所以我可以再拨打电话:

import cmd.driver.cli.NetworkConfig 
. 
. 
. 
config_driver = cmd.driver.cli.NetworkConfig.new(...) 

hmmmm ...我意识到,在几个意思,这可能不是“Python化”,而我不喜欢瞎幕后太多(这种事总是有风险的),但也许这是得到我想要的东西的方法,如果我死定了它...

.................. ...................................

后+ 1周的额外评论:

天哪没有得票率?一种严肃的问题。也许我不应该说我会如何在Perl中这样做...... :-啊啊,好吧。

+0

在post + 1周的额外评论: – Bruce

回答

0

我的命题:使用__ import__来定义你的函数。

def myInit(pathImport, *args): 
    t = __import__(pathImport+".network_config", globals(), locals(), [], 0) 
    return t.NetworkConfig(*args) 

和使用

config_driver = myInit('cmd.driver.cli', ...) 
+0

谢谢,但似乎很奇怪,我需要做一个非常标准的模式,在一个文件中的单个类,并有一个合理的完整的类名称那个班。我很感激你花时间建议。谢谢。 – Bruce

0

尝试这样的事情在你的顶层模块或__init__.py

# import submodules, exposing them to things that import this module directly 

from cmd.interface.cli import mgmt 
from cmd.interface.cli import support 
from cmd.interface import rest 

from cmd.driver.cli import stats as driver_stats 
from cmd.result.cli import stats as result_stats 

# hide unneeded variables from things that import this module (optional) 

__all__ = ['mgmt', 'support', 'rest', 'driver_stats', 'result_stats'] 

这将会使简化的名称作为模块成员变量任何引用你的根模块。您甚至可以在层次结构的多个级别上对此模式进行变化。

+0

我认为我不想简化名称。在使用时,全名的每一位都有重要的信息供维护人员轻松看到。例如,在一段代码中,我将要x = cmd.driver.cli.xX,并且在相关的部分中,我将使用x = cmd.driver.rest.xX,并且对于其他结果对象。在这个模型中,那么,我想我可以说“从cmd.driver.cli.x导入X为cmd_driver_cli_X”,然后是x = cmd_driver_cli_X(...)。嗯...更好 - 也许一样好,我想... – Bruce

+0

@布鲁斯你不必在顶部模块做到这一点。您提供的有关cmd.driver.cli.NetworkConfig的示例可以通过将NetworkConfig导入到cmd.driver.cli下的init文件中来实现。许多python模块为子模块和最高级别下的成员提供便利或描述性访问,具体取决于用户的需求。 – Uncommented

+0

这些评论很难进行多少讨论。我以比这里的工作更重要的细节作出回应的标准方式是什么?我应该编辑我的帖子吗?或回答帖子?感谢你的帮助。 – Bruce