• Python的import嵌套



    [root@fuel ~]# vi /var/lib/docker/devicemapper/mnt/4da57a0078c9d3f32e819373b67de41da37c34a27ee03f74016427e0223df5f2/rootfs/usr/lib/python2.6/site-packages/nailgun/db/sqlalchemy/models/node.py
         88
         89 class Node(Base):

        304     @classmethod
        305     def delete_by_ids(cls, ids):
        306         db.query(Node).filter(Node.id.in_(ids)).delete('fetch')

         32 from nailgun.db import db
    可看出引用了/usr/lib/python2.6/site-packages/nailgun/db.py中的db变量。


    发现db.py不存在:
    [root@fuel ~]# ls -l /var/lib/docker/devicemapper/mnt/4da57a0078c9d3f32e819373b67de41da37c34a27ee03f74016427e0223df5f2/rootfs/usr/lib/python2.6/site-packages/nailgun/db.py


    进入nailgun目录:
    [root@fuel ~]# cd /var/lib/docker/devicemapper/mnt/4da57a0078c9d3f32e819373b67de41da37c34a27ee03f74016427e0223df5f2/rootfs/usr/lib/python2.6/site-packages/nailgun
    [root@fuel nailgun]# ls
    发现nailgun目录下还有一个db目录:
    [root@fuel nailgun]# cd db
    [root@fuel db]# ls
    deadlock_detector.py   deadlock_detector.pyo  __init__.pyc  migration
    deadlock_detector.pyc  __init__.py            __init__.pyo  sqlalchemy
    从网络了解到:“__init__.py”会在被导入时执行,因此这是Python另一种导入方式。


    [root@fuel db]# vi __init__.py
         17 from nailgun.db.sqlalchemy import db
    可看出引用了/usr/lib/python2.6/site-packages/nailgun/db/sqlalchemy.py中的db变量。
    同样不存在sqlalchemy.py,但存在sqlalchemy目录:


    [root@fuel sqlalchemy]# vi __init__.py
         80 db = scoped_session(
         81     sessionmaker(
         82         autoflush=True,
         83         autocommit=False,
         84         bind=engine,
         85         query_cls=query_class,
         86         class_=session_class
         87     )
         88 )


         24 from sqlalchemy.orm import scoped_session
         26 from sqlalchemy.orm import sessionmaker

    可看出引用了/usr/lib/python2.6/site-packages/sqlalchemy/orm.py中的scoped_session、sessionmaker变量。不存在orm.py,且不存在orm目录。


         19 from sqlalchemy import create_engine
         31 from nailgun.db.sqlalchemy import utils
         35 db_str = utils.make_dsn(**settings.DATABASE)
         36 engine = create_engine(db_str, client_encoding='utf8')
    可看出引用了/usr/lib/python2.6/site-packages/nailgun/db/sqlalchemy.py中的utils对象或/usr/lib/python2.6/site-packages/nailgun/db/sqlalchemy/__init__.py中引用了utils对象。
    db_str明显是数据库连接字符串,内容是“postgresql://nailgun:dvbbYDuU@168.5.21.2:5432/nailgun”。


         72 if settings.DEVELOPMENT:
         73     query_class = DeadlockDetectingQuery
         74     session_class = DeadlockDetectingSession
         75 else:
         76     query_class = NoCacheQuery
         77     session_class = Session

         32 from nailgun.settings import settings





    进入docker:
    [root@fuel sqlalchemy]# docker exec -it fuel-core-6.1-nailgun /bin/sh
    sh-4.1# cd /usr/lib/python2.6/site-packages/nailgun/db/sqlalchemy
    sh-4.1# vi __init__.py
         33 #zzy added
         34 from nailgun.logger import logger
         35 import sys

         82 #zzy added
         83 logger.warning('____ffff____')
         84 logger.warning(sys.path)


    sh-4.1# python __init__.py
    sh-4.1# tail -n 20 /tmp/nailgun.log |grep WARNING
    2016-01-27 06:24:20.257 WARNING [7f92c5287700] (__init__) ____ffff____
    2016-01-27 06:24:20.257 WARNING [7f92c5287700] (__init__) ['/usr/lib/python2.6/site-packages/nailgun/db/sqlalchemy', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib/python2.6/site-packages']


    orm.py或orm目录使用以下命令查找:
    ls /usr/lib/python2.6/site-packages/nailgun/db/sqlalchemy/sqlalchemy/orm*
    ls /usr/lib64/python26.zip/sqlalchemy/orm*
    ls /usr/lib64/python2.6/sqlalchemy/orm*
    ls /usr/lib64/python2.6/plat-linux2/sqlalchemy/orm*
    ls /usr/lib64/python2.6/lib-tk/sqlalchemy/orm*
    ls /usr/lib64/python2.6/lib-old/sqlalchemy/orm*
    ls /usr/lib64/python2.6/lib-dynload/sqlalchemy/orm*
    ls /usr/lib64/python2.6/site-packages/sqlalchemy/orm*
    ls /usr/lib/python2.6/site-packages/sqlalchemy/orm*


    最终发现:
    sh-4.1# cd /usr/lib64/python2.6/site-packages/sqlalchemy/orm
    sh-4.1# vi __init__.py
         63 from .scoping import (
         64     scoped_session
         65 )
         56 from .session import (
         57     Session,
         58     object_session,
         59     sessionmaker,
         60     make_transient,
         61     make_transient_to_detached
         62 )

    从网络了解到,“.scoping”指“__init__.py”同一级目录的“scoping.py”:
    sh-4.1# vi scoping.py
         14 __all__ = ['scoped_session']
         15
         16
         17 class scoped_session(object):
         18     """Provides scoped management of :class:`.Session` objects.
    “__all__”定义只导出scoped_session类(当scoping.py被import的时候)。


    sh-4.1# vi session.py
         27 __all__ = ['Session', 'SessionTransaction',
         28            'SessionExtension', 'sessionmaker']

       2253 class sessionmaker(_SessionClassMethods):
       2254
       2255     """A configurable :class:`.Session` factory.
       2256
       2257     The :class:`.sessionmaker` factory generates new
       2258     :class:`.Session` objects when called, creating them given
       2259     the configurational arguments established here.



    /usr/lib64/python2.6/site-packages/sqlalchemy/orm/scoping.py
        105     def query_property(self, query_cls=None):
        106         """return a class property which produces a :class:`.Query` object
        107         against the class and the current :class:`.Session` when called.
        108
        109         e.g.::
        110
        111             Session = scoped_session(sessionmaker())
        112
        113             class MyClass(object):
        114                 query = Session.query_property()
        115
        116             # after mappers are defined
        117             result = MyClass.query.filter(MyClass.name=='foo').all()
        118
        119         Produces instances of the session's configured query class by
        120         default.  To override and use a custom implementation, provide
        121         a ``query_cls`` callable.  The callable will be invoked with
        122         the class's mapper as a positional argument and a session
        123         keyword argument.
        124
        125         There is no limit to the number of query properties placed on
        126         a class.
        127
        128         """
        129         class query(object):
        130             def __get__(s, instance, owner):
        131                 try:
        132                     mapper = class_mapper(owner)
        133                     if mapper:
        134                         if query_cls:
        135                             # custom query class
        136                             return query_cls(mapper, session=self.registry()        )
        137                         else:
        138                             # session's configured query class
        139                             return self.registry().query(mapper)
        140                 except orm_exc.UnmappedClassError:
        141                     return None
        142         return query()
        143


  • 相关阅读:
    字符串处理类
    PageHelper
    JavaScriptPlus操作类
    Http 数据操作
    解压 压缩 C#
    验证码生成 C#
    MySecurity(安全类)
    博客搬迁至wordpress站点
    我的前端MVC之路
    三个css3趣玩小试
  • 原文地址:https://www.cnblogs.com/endoresu/p/5163317.html
Copyright © 2020-2023  润新知