首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在__init__自动初始化的"Lazy“属性

在__init__自动初始化的"Lazy“属性
EN

Stack Overflow用户
提问于 2017-02-21 03:54:47
回答 2查看 1.1K关注 0票数 0

我想使用一些类似于通常的懒惰性装饰器,但由于TensorFlow的工作方式和使用方式,我需要在最新的__init__上自动初始化所有的惰性属性( TensorFlow部件不是问题的一部分,但有关我的意思,请参阅这里 )。所谓“初始化”,我的意思是调用getattr一次运行属性方法并缓存结果。

以下工作已经完成:

代码语言:javascript
运行
AI代码解释
复制
import functools

def graph_property(getter):
    property_name = getter.__name__
    attribute = '_cache_' + property_name

    @property
    @functools.wraps(getter)
    def decorated(self):
        if not hasattr(self, attribute):
            setattr(self, attribute, getter(self))
            self._graph.append(property_name) # for illustration
            print('Initializing ' + property_name)
        return getattr(self, attribute)

    return decorated


class Test:
    def __init__(self):
        self._graph = []
        self.inputs    # DON'T LIKE TO DO THIS
        self.do_stuff  # AND THIS

    @graph_property
    def inputs(self):
        return 42.0

    @graph_property
    def do_stuff(self):
        return self.inputs + 1.0


if __name__ == '__main__':
    t = Test()
    print(t._graph)

但是,最好摆脱对self.input__init__中的self.do_stuff的手动调用--这很快就变得乏味了。

我在考虑多种“记住”属性的方法,哪些属性是列表中某个位置的graph_property,但我认为所有这些都必须失败,因为在应用装饰符时,类还不为它所知(更不用说self了)。

我可以想象的一种工作方式是给返回的decorated对象一些标记属性,并为Test编写一个元类,它查看所有方法,收集带有这个标记的方法,并以某种方式为它们创建一个初始化器。我未能实现这一点,因为我对元类非常不熟悉,而且property描述符不允许我添加属性。

所述方法是否可行(如果可行,如何实施)?还是有一种更简单的方法(没有人工开销,语法也一样好),而我只是没有看到它?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-21 04:23:49

您可以添加一个简单的property并定义一个子类,然后在__init__方法中执行与这个自定义属性相关的所有初始化。通过这种方式,您可以选择希望它们初始化的类以及不希望初始化它们的类。

代码语言:javascript
运行
AI代码解释
复制
import functools


class lazy_property(property):
    """
    This class will help us in identifying our lazy properties, so that we
    don't confuse them with normal properties. 
    """
    pass

def graph_property(getter):
    property_name = getter.__name__
    attribute = '_cache_' + property_name

    @lazy_property
    @functools.wraps(getter)
    def decorated(self):
        if not hasattr(self, attribute):
            setattr(self, attribute, getter(self))
            self._graph.append(property_name)  # for illustration
            print('Initializing ' + property_name)
        return getattr(self, attribute)

    return decorated

class InitializeLazyPropertiesMixin:
    """
    This mixin does all of the work of initializing lazy properties
    """
    def __init__(self):
        cls = type(self)
        fields = (k for k in dir(cls) if isinstance(getattr(cls, k), lazy_property))
        for field in fields:
            getattr(self, field)


class Test(InitializeLazyPropertiesMixin):
    def __init__(self):
        self._graph = []
        # Whenever you're inheriting from this mixin make sure to call
        # super `__init__` method.
        super().__init__()

    @graph_property
    def inputs(self):
        return 42.0

    @graph_property
    def do_stuff(self):
        return self.inputs + 1.0

class Test1:
    """
    Just another class that doesn't require initializing any of the lazy properties
    """
    def __init__(self):
        self._graph = []

    @graph_property
    def inputs(self):
        return 42.0

    @graph_property
    def do_stuff(self):
        return self.inputs + 1.0

演示输出:

代码语言:javascript
运行
AI代码解释
复制
>>> t = Test()
Initializing inputs
Initializing do_stuff
>>> print(t._graph)
['inputs', 'do_stuff']
>>> t = Test1()
>>> print(t._graph)
[]
>>> t.inputs
Initializing inputs
42.0
>>> t._graph
['inputs']
票数 1
EN

Stack Overflow用户

发布于 2017-02-21 04:12:37

由于您完全控制了属性和类层次结构,所以只需标记您想要的属性,并且在基类__init__方法中包含调用所有属性的代码。

因此,首先,在装饰器中,在graph_property装饰器上设置一个变量,以便标记要初始化的方法。由于property对象与函数不同,不能分配任意属性,因此修复方法是将Python的本机属性包装在用户定义的类中:

代码语言:javascript
运行
AI代码解释
复制
class MarcableProperty(property):
    pass

def graph_property(getter):
    property_name = getter.__name__
    attribute = '_cache_' + property_name

    @MarcableProperty
    @functools.wraps(getter)
    def decorated(self):
        ...

    decorated._graph_initialize = True
    return decorated

然后,在基类或混合类上为所有其他类执行以下操作:

代码语言:javascript
运行
AI代码解释
复制
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    for cls_member_name in dir(self.__class__): 
         # "dir" is good because it automatically looks
         # at the superclasses as well
         cls_member = getattr(self.__class__, cls_member_name)
         if getattr(cls_member, "_graph_initialize", False):
              # Fetch property, initializing its value:
              getattr(self, cls_member_name)

应该是这样的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42366615

复制
相关文章
extjs 部署时动态切换上下文路径
修改index.html ... <script type="text/javascript"> // 获取首页上下文路径 var basePath = window.kk; basePath = basePath.substr(0, basePath.lastIndexOf('index.html')); // 创建base标签 var base = document.createElement("base"); base.setAttribute("hre
路过君
2020/06/19
4540
fiddler使用——配置抓取https,出现提示“禁用解密”“单击配置”
自己在设置fiddler抓https的时候,浏览器总是提示:此证书不受信任;中午没午睡下午一直昏沉沉的,弄了好久,终于想起来是证书的问题;度娘有个不错的答案,这里分享一下!给以后有相同问题的朋友,也同时作为自己的一个记录。(PS:自己喜欢用火狐,所以自己是在火狐上设置的,其他大同小异,这位童鞋说的比较清楚)
呆呆
2021/05/25
2.3K0
vue 实现标签切换
文章持续更新,阅读最新版文章请查看 https://www.itshutong.com/articles/429/vue-realizes-label-switching
章鱼喵
2020/02/19
1.3K0
视频标签栏切换
代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>视频标签栏切换</title> <style> * { padding: 0; margin: 0; }
王凡汎
2020/05/07
6860
tab标签页切换时Echarts加载不正常的问题
我有两个选项卡,一个用来显示Echarts图表,一个用来显示Echarts图表的数据源
别团等shy哥发育
2023/02/25
2.2K0
tab标签页切换时Echarts加载不正常的问题
后台系统设计(上篇:选择)
在单个选项下,存在多组互斥选项,且互斥选项组之间存在一定关系,可以考虑混用分段控件和常规按钮,由于分段控件在视觉上占用更大的面积,故给人在层级上更加置前。
霖酱
2018/10/10
10.1K0
后台系统设计(上篇:选择)
win禁用shift切换输入法
在很多场景下,我们都会使用到shift来完成一些功能,最常见的就是输出键盘上面一排标点符号,但是往往在使用shift时会出现切换输入法的情况,在一些仅英文或者中文输入的场合切换会对工作效率造成影响,这里介绍禁用shift切换输入法的方法,仅仅采用ctrl+空格的方式完成切换输入法。
timerring
2022/09/21
6.1K0
win禁用shift切换输入法
使用 HTML meta 标签来禁用缓存
在测试某个 SPA 项目时,发现更改后 Chrome 浏览器页面刷新还是使用之前的版本。经调查发现 Chrome 默认缓存值为 300 秒。
李维亮
2021/07/08
4.4K0
含有复选框的表格显示与隐藏切换
如果使用v-if,注意使用this.nextTick,并且this.nextTick 放的位置在里面,不要显示表格的时候就使用this.
tianyawhl
2020/12/16
2.3K0
含有复选框的表格显示与隐藏切换
如何禁用 Gmail 的分类(Categories )标签
但是有时候因为这个分类的存在,导致我们经常找不到邮件,很多人可能还是习惯按照时间的顺序来处理邮件。
HoneyMoose
2021/09/11
1.3K0
如何禁用 Gmail 的分类(Categories )标签
jQuery 双击事件(dblclick)时,不触发单击事件(click)
在jQuery的事件绑定中,执行双击事件(dblclick)时能触发两次单击事件(click)。即一个标签元素(如div等),如果元素同时绑定了单击事件(click)和双击事件(dblclick),那么执行单击事件(click)时,不会触发双击事件(dblclick), 执行双击事件(dblclick)时却会触发两次单击事件(click)。 先看一下点击事件的执行顺序:
飞奔去旅行
2019/06/13
5.6K0
小程序标签页切换效果
小程序标签页切换效果 效果: image.png 效果 .wxml <view class='topTabSwiper'> <view class='tab {{currentData == 0
达达前端
2019/07/04
2.2K0
vim-tabe多标签切换
原文链接:https://www.cnblogs.com/liqiu/archive/2013/03/26/2981949.html
ccf19881030
2019/11/18
2.2K0
VBA专题10-8:使用VBA操控Excel界面之在功能区中添加内置控件
4. 在CustomUI Editor中,单击“插入”并选择“Office 2007 Custom UI Part”。之所以选择这个选项,是使工作簿与Excel 2007及以后的版本兼容。
fanjy
2020/11/09
6.9K0
VBA专题10-8:使用VBA操控Excel界面之在功能区中添加内置控件
认识基本的mfc控件
  几乎可以在每个windows程序中都看到按钮、复选框、文本框以及下拉列表等等,这些都是控件。而且很多常用的控件已经内置到操作系统当中了,在Visual C++中,这些常用控件已经简答到能用“拖放”这种窗口设计方法来将他们放置到一个对话框中。
用户2038589
2018/09/06
3.5K0
认识基本的mfc控件
动态加载 ExtJS 类库
ExtJS 是一个非常优秀的 JS 框架, 由于 ExtJS 自身非常庞大, 用于开发测试的 ext-all-debug.js 文件达到了 3.24M , 如果是再加载带注释的 ext-all-debug-w-comments.js 则更是达到了 6M , 可以说是非常庞大了, 因此动态加载 ExtJS 是很有必要的, 接下来就介绍如何对 ExtJS 做动态加载。
beginor
2020/08/10
2.3K0
动态加载 ExtJS 类库
当不使用会话状态时禁用它
并不是所有的应用程序或页都需要针对于具体用户的会话状态,您应该对任何不需要会话状态的应用程序或页禁用会话状态。
Java架构师必看
2021/03/22
5310
选择篇(039)-单击按钮时event.target是什么?
导致事件的最深嵌套元素是事件的目标。你可以通过event.stopPropagation停止冒泡
齐丶先丶森
2022/05/12
1.7K0
CSS+JS实现tab标签切换
循环将所有的内容标签隐藏,并将tab标题栏的active样式清除,完了之后设置选中标签的内容显示,并给tab标题栏添加active样式。
牛老师讲GIS
2018/10/23
11.8K0
CSS+JS实现tab标签切换
点击加载更多

相似问题

从所有具有"Where“条件的数据库表中检索所有行

23

从具有可选值的数据库表中检索所有组合

13

从具有相同id的多个表中检索数据

12

如何从具有相同列名多个表中检索数据

20

从mysql中具有相同字段的多个表中检索数据

14
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档