使用类装饰器来实现后期初始化 [英] Use a class decorator to implement late-initialization

查看:66
本文介绍了使用类装饰器来实现后期初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一些需要连接到数据库的类。仅在执行实际操作时才真正需要连接。我想延迟连接阶段,直到真正需要它为止。为此,我想做类似的事情:

I am using some classes which need to connect to databases. The connection is only really needed when performing a real action. I want to delay the connection phase until it is really needed. For that, I want to do something similar to this:

class MyClass

    def __init__(self):
        self.conn = None

    def connect(self):
        if self.conn : return
        self.conn = ConnectToDatabase()

    @connect
    def do_something1(self):
        self.conn.do_something1()

    @connect
    def do_something2(self):
        self.conn.do_something2()

但是我不知道如何定义 connect 该类的装饰器。

But I do not know how to define the connect decorator for the class.

我当然可以做这样的事情:

I could of course do something like this:

    def do_something1(self):
        self.connect()
        self.conn.do_something1()

但是使用装饰器似乎更易读。

But using decorators seems a more readable solution. Is it possible?

推荐答案

不是尝试装饰需要连接的功能,而是使用属性来获取连接本身。 / p>

Rather than trying to decorate the functions that require connections, use a property for getting the connection itself.

class MyClass(object):

    def __init__(self):
        self._conn = None

    @property
    def conn(self):
        if self._conn is None:
            self._conn = ConnectToDatabase()
        return self._conn

    def do_something1(self):
        self.conn.do_something1()

    def do_something2(self):
        self.conn.do_something2()

作为一个简单的装饰器示例,请假装F.J的答案:

As for a straight decorator example, playing off F.J's answer:

def prerequisite(prerequisite_function, *pre_args, **pre_kwargs):
    def wrapper(func):
        def wrapped(self, *args, **kwargs):
            prerequisite_function(self, *pre_args, **pre_kwargs)
            return func(self, *args, **kwargs)
        return wrapped
    return wrapper

 class MyClass(object):

     def __init__(self):
         self.conn = None

     def connect(self):
         if self.conn is None:
             self.conn = ConnectToDatabase()

     @prerequisite(connect)
     def do_something(self):
         self.conn.do_something()

您还可以通过创建描述符来使前提条件更加健壮,以便它对于函数和静态方法以及类和实例方法可以正确运行。

You could also make prerequisite more robust by making it create descriptors so that it can behave correctly for functions and static methods as well as class and instance methods.

这篇关于使用类装饰器来实现后期初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆