推荐学习书目
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 ·
    PRO
    · Aug 6, 2018 · 2984 views
    This topic created in 2860 days ago, the information mentioned may be changed or developed.

    我想要做到这样的效果:

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

    我这么写,一直错误

    12 replies    2018-08-07 09:08:22 +08:00
    awah
        1
    awah  
       Aug 6, 2018 via Android   ❤️ 1
    getattr(v, None)?
    Cheez
        2
    Cheez  
    OP
    PRO
       Aug 6, 2018
    @luguhu #1 啊?什么意思?我要的不是 None 啊
    awah
        3
    awah  
       Aug 6, 2018
    getattr(obj, v, defult)
    obj: 对象
    v: 属性名
    defult: 默认值
    Trim21
        4
    Trim21  
       Aug 6, 2018 via Android
    hasattr()?
    Cheez
        5
    Cheez  
    OP
    PRO
       Aug 6, 2018 via Android
    @Trim21 每次调用 hasattr,我的 getattr 魔术方法总会捕捉到错误........心累
    Cheez
        6
    Cheez  
    OP
    PRO
       Aug 6, 2018 via Android
    @luguhu 我知道啊,可是我要的那个值需要联网获取啊。

    我给你解释一下吧。

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

    @luguhu
    nice
    Cheez
        9
    Cheez  
    OP
    PRO
       Aug 6, 2018
    @BingoXuan #8 可是我的用户是这么写代码的:

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

    这两个属性就是高级属性,而且获取完 author 之后,name 还是 author 的高级属性,必须重新获取
    Cheez
        10
    Cheez  
    OP
    PRO
       Aug 6, 2018
    不过没事了,我最后自己解决了(笑哭

    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  
       Aug 7, 2018
    感觉你用描述符更好
    Cheez
        12
    Cheez  
    OP
    PRO
       Aug 7, 2018
    @WilliamYang #11 描述符是针对类的,我这里只是属性
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2835 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 12:58 · PVG 20:58 · LAX 05:58 · JFK 08:58
    ♥ Do have faith in what you're doing.