模块如何从一个导入可见而从另一个导入不可见?
Posted
技术标签:
【中文标题】模块如何从一个导入可见而从另一个导入不可见?【英文标题】:How can module be visible from one import and not visible from another? 【发布时间】:2012-12-12 05:00:00 【问题描述】:所以我有一个使用pymysql
的应用程序,纯python mysql 客户端实现。在我做出回应之前,我想强调一个事实,即我不愿意使用不同的 mysql 驱动程序。
我有一个模块实现了由 MySQL 支持的数据结构。该模块的要点如下:
import pymysql
class Whatever:
def __init__(self):
# Debug statement
print dir(pymysql)
# use the cursors submodule
self.conn = pymysql.connect( ... , cursorclass=pymysql.cursors.DictCursor)
当我在我的测试文件中导入它时,一切都很好。这是print
语句的输出。特别是,我提请您注意游标模块:
['BINARY', 'Binary', 'Connect', 'Connection', 'DATE', 'DATETIME', 'DBAPISet', 'DataError',
'DatabaseError', 'Date', 'DateFromTicks', 'Error', 'FIELD_TYPE', 'IntegrityError',
'InterfaceError', 'InternalError', 'MySQLError', 'NULL', 'NUMBER', 'NotSupportedError',
'OperationalError', 'ProgrammingError', 'ROWID', 'STRING', 'TIME', 'TIMESTAMP', 'Time',
'TimeFromTicks', 'Timestamp', 'TimestampFromTicks', 'VERSION', 'Warning', '__all__',
'__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__',
'__version__', 'apilevel', 'charset', 'connect', 'connections', 'constants', 'converters',
'cursors', 'err', 'escape_dict', 'escape_sequence', 'escape_string', 'get_client_info',
'install_as_MySQLdb', 'paramstyle', 'sys', 'thread_safe', 'threadsafety', 'times', 'util',
'version_info']
当我从主文件导入模块时,我得到一个AttributeError
:
Traceback (most recent call last):
File "xxx.py", line 72, in <module>
passwd='', db='test_db')
File "yyy.py", line 26, in __init__
passwd=passwd, db=db, cursorclass=pymysql.cursors.DictCursor)
AttributeError: 'module' object has no attribute 'cursors'
dir
打印的输出如下:
['BINARY', 'Binary', 'Connect', 'Connection', 'DATE', 'DATETIME', 'DBAPISet',
'DataError', 'DatabaseError', 'Date', 'DateFromTicks', 'Error', 'FIELD_TYPE',
'IntegrityError', 'InterfaceError', 'InternalError', 'MySQLError', 'NULL', 'NUMBER',
'NotSupportedError', 'OperationalError', 'ProgrammingError', 'ROWID', 'STRING', 'TIME',
'TIMESTAMP', 'Time', 'TimeFromTicks', 'Timestamp', 'TimestampFromTicks', 'VERSION',
'Warning', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__',
'__path__', '__version__', 'apilevel', 'charset', 'connect', 'constants', 'converters',
'err', 'escape_dict', 'escape_sequence', 'escape_string', 'get_client_info',
'install_as_MySQLdb', 'paramstyle', 'sys', 'thread_safe', 'threadsafety', 'times',
'version_info']
值得注意的是,cursors
不存在。检查pymysql.__file__
在两种情况下都是一样的,输出是:
__init__.py charset.py connections.py constants converters.pyc cursors.pyc err.pyc times.py util.py
__init__.pyc charset.pyc connections.pyc converters.py cursors.py err.py tests times.pyc util.pyc
显然cursors.py
在那里。那么是什么给出的呢?
【问题讨论】:
您的代码实际上是什么样的?可能是循环导入问题。 【参考方案1】:您需要在文件顶部添加明确的import pymysql.cursors
。
cursors
子包未列在pymysql
的__all__
中,因此当您只执行import pymysql
时不会导入。
【讨论】:
是的,至少根据 pymysql 的 github 上的最新消息。 github.com/petehunt/PyMySQL/blob/master/pymysql/__init__.py看底部。 它确实在__all__
中提到了它,但它实际上并没有将子包导入命名空间,因此实际上并未作为属性导出。
我可以确认import pymysql
不会自动为我导入pymysql.cursors
。当我被殴打时,我正在写相同的答案,所以我赞成这个。
它间接地这样做了,虽然不是自动的,因为 Connect 函数从连接中导入 Connection,而后者又从游标中导入 Cursor。显然,这里没有提到其他重要的事情。
@sr2222: ?你是说import pymysql
和import pymysql; pymysql.cursors
不会为你提出AttributeError
?以上是关于模块如何从一个导入可见而从另一个导入不可见?的主要内容,如果未能解决你的问题,请参考以下文章