西部数码主机 | 阿里云主机| 虚拟主机 | 服务器 | 返回乐道官网
当前位置: 主页 > 开发教程 > python教程 >

python全局变量的正确打开方式

时间:2016-04-30 00:21来源:未知 作者:好模板 点击:
在python中使用单例模式非常的容易。 你在一个模块中初始化一个对象,然后去引用这个对象就行了。因为python中万物皆对象,哪怕是一个包(package),也可以当作一个对象。但是这种

在python中使用单例模式非常的“容易”。

你在一个模块中初始化一个对象,然后去引用这个对象就行了。因为python中万物皆对象,哪怕是一个包(package),也可以当作一个对象。但是这种方式并不好,因为你的代码会看上去非常耦合,所以我从来不建议把包当成一个对象,你仅仅当成一个包就可以了。我再解释一下我的意思,就是你不应该直接从一个包中import一个对象,虽然你可以这么做。你应该import进来一个类,然后通过这个类,来创建对象,这才是单例模式正确的使用方式。而且对于IDE来说,那种从包中导入的对象,因为是动态的,所以你goto define也是找不到的。

而且如果你明白了我的意思,这些来来回回传递的对象,当你想要把一个函数封装出来单独写测试时,你会发现要把这些对象当做上下文当做传入的时候,简直头疼的要死。

下面将通过三个例子,来说明我的观点,第一个例子是我认为python日志的正确使用方式,第二个是tornado中是如何使用ioloop这个全局对象的,第三个例子是我认为的一个项目的配置文件应该使用的方式。

日志的使用方式

我现在接手的项目,这个web服务的日志就是我说的那样,他们在一个包中初始化了日志对象,比如这个叫main_logger, 那个叫biz_logger,然后到处引用这些对象。

实际上我自己的代码中,获取日志的方式简单有粗暴:

logger = logging.getLogger(__name__)

然后你在一个统一的地方为这个 name 配置handler就行了。而且实际上的工作量要比你想象的少很多,因为像”business.handler”,这样的name是可以继承”business”的日志配置的。你设计好包的格式,然后配置他们的日志打印方式,对于单测,只要以另一种方式初始化这些logger就行了,甚至可以不管,让他们使用root默认。

因为你的代码并没有“动态耦合”。

tornado中的ioloop

还记得你怎么写tornado的代码吗?

tornado.ioloop.instance().start()

我们可以去看tornado的ioloop源码

@staticmethod
def instance():
    """Returns a global `IOLoop` instance.
    Most applications have a single, global `IOLoop` running on the
    main thread.  Use this method to get this instance from
    another thread.  In most other cases, it is better to use `current()`
    to get the current thread's `IOLoop`.
    """
    if not hasattr(IOLoop, "_instance"):
        with IOLoop._instance_lock:
            if not hasattr(IOLoop, "_instance"):
                # New instance after double check
                IOLoop._instance = IOLoop()
    return IOLoop._instance

注意这里加了一个线程锁,相当于在类中维护了这个单例对象,你可以把这个例子用在你的单例对象中。

配置文件的使用方式

我的配置也是使用单例的方式,载入到服务中,然后instance去引用它。

当然我的配置类,可以有各种方式初始化其中的值,比如用json,用yaml,用conf文件,等等。。

需要注意的是,不要给你的单例对象写构造函数( init ),因为即使是单例模式的对象,也会每次调用你的构造函数,防止你每次获取单个例都刷新了所有东西。

还要注意的是,我现在维护的代码,有之前的同事,自己写了一个装饰器来装饰类,代码和上面的装饰器思路一样,使它变成一个单例类。这个问题是啥?被装饰器包裹的类,变成了一个函数。

(责任编辑:好模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容