V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Cheez
V2EX  ›  Python

当调用的属性不存在时,初始化再返回值,在 Python 里面怎么写?

  •  
  •   Cheez · 2018-08-06 18:42:28 +08:00 · 2463 次点击
    这是一个创建于 2061 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想要做到这样的效果:

    • 从返回的 JSON 中读取作者信息,转化成 People 对象,此时的 People 对象只有 id 等基本属性,描述、粉丝数需要额外联网获取
    • 当访问 People 的基本属性时,直接返回;当访问属性不存在时,进行联网初始化,之后返回值,期间要判断这个属性存不存在,因为有可能 People 压根就没有这个属性;
        def __getattr__(self, v):
    
            self.init()
            try:
                return self.__dict__[v]
            except Exception as e:
                pass
    

    我这么写,一直错误

    12 条回复    2018-08-07 09:08:22 +08:00
    luguhu
        1
    luguhu  
       2018-08-06 18:48:46 +08:00 via Android   ❤️ 1
    getattr(v, None)?
    Cheez
        2
    Cheez  
    OP
       2018-08-06 19:18:13 +08:00
    @luguhu #1 啊?什么意思?我要的不是 None 啊
    luguhu
        3
    luguhu  
       2018-08-06 19:51:49 +08:00
    getattr(obj, v, defult)
    obj: 对象
    v: 属性名
    defult: 默认值
    Trim21
        4
    Trim21  
       2018-08-06 20:03:52 +08:00 via Android
    hasattr()?
    Cheez
        5
    Cheez  
    OP
       2018-08-06 21:46:44 +08:00 via Android
    @Trim21 每次调用 hasattr,我的 getattr 魔术方法总会捕捉到错误........心累
    Cheez
        6
    Cheez  
    OP
       2018-08-06 21:47:57 +08:00 via Android
    @luguhu 我知道啊,可是我要的那个值需要联网获取啊。

    我给你解释一下吧。

    就是我开始拿到的是一个每个用户简要的信息,当要访问用户的高级的信息的时候,就联网初始化,返回值。
    Trim21
        7
    Trim21  
       2018-08-06 22:06:36 +08:00
    @Cheez #5 是我学艺不精了...
    本来就是取不到某个属性的时候才会调用__getattr__ 如果__getattr__被调用了, 而且对应的 key 是一个合法的 key 的话直接初始化高级数据就可以了
    BingoXuan
        8
    BingoXuan  
       2018-08-06 22:08:24 +08:00
    @Cheez
    一楼已经解释得很清楚了。getattr 获取不到给定对象得指定属性时候就回返回 defualt 得值,这个值设为初始化函数调用就是联网获取数据了。如 getattr(a,'no_exist_attribute',requests.get('https://www.baidu.com').content)

    @luguhu
    nice
    Cheez
        9
    Cheez  
    OP
       2018-08-06 23:54:50 +08:00
    @BingoXuan #8 可是我的用户是这么写代码的:

    for v in Question('5546455002').answers():
    print(v.content)
    print(v.author.name)

    这两个属性就是高级属性,而且获取完 author 之后,name 还是 author 的高级属性,必须重新获取
    Cheez
        10
    Cheez  
    OP
       2018-08-06 23:56:17 +08:00
    不过没事了,我最后自己解决了(笑哭

    def __getattr__(self, v):
    if self.is_init == False:
    self.is_init = True
    self.init()
    return super().__getattribute__[v]


    @BingoXuan #8
    @Trim21 #7
    @luguhu #3
    WilliamYang
        11
    WilliamYang  
       2018-08-07 00:38:26 +08:00
    感觉你用描述符更好
    Cheez
        12
    Cheez  
    OP
       2018-08-07 09:08:22 +08:00
    @WilliamYang #11 描述符是针对类的,我这里只是属性
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3076 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 14:32 · PVG 22:32 · LAX 07:32 · JFK 10:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.