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
yangtukun1412
V2EX  ›  Python

怎样判断变量是一个(非 builtin)类的实例?

  •  
  •   yangtukun1412 · 2015-06-02 10:34:34 +08:00 · 2277 次点击
    这是一个创建于 3462 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果使用 old style class 的风格,可以这样判断:

    class A:
        pass
    
    a = A()
    isinstance(a, types.InstanceType)  # true
    

    但是使用 new style class 的话,上述方法无法使用。那么,需要怎样判断呢?

    9 条回复    2015-06-04 09:55:12 +08:00
    knightdf
        1
    knightdf  
       2015-06-02 15:29:42 +08:00
    isinstance(a,A)
    yangtukun1412
        2
    yangtukun1412  
    OP
       2015-06-02 17:03:39 +08:00
    @knightdf

    并不是要判断 a 是 A 的实例,而是要判断 a 是一个类的实例。
    knightdf
        3
    knightdf  
       2015-06-02 17:25:01 +08:00
    @yangtukun1412 那在Python里面a必然是一个“类”的实例,不用判断,有意义?
    ruoyu0088
        4
    ruoyu0088  
       2015-06-02 20:49:42 +08:00
    请详细说明你为了实现什么目标而需要判断非 builtin类?非 builtin类的定义是什么?types模块中之外的类都可以认为是非 builtin类吗?
    yangtukun1412
        5
    yangtukun1412  
    OP
       2015-06-03 10:25:47 +08:00
    @knightdf

    所以在标题里写明了是区分 非builtin 的类
    yangtukun1412
        6
    yangtukun1412  
    OP
       2015-06-03 10:32:16 +08:00
    @ruoyu0088

    是的,可以认为 types 模块之外的都算。

    目前的问题是发现公司旧代码中有个方法需要对传入的对象进行操作,大致的逻辑是这样的:

    ```Python

    def func(obj):
    if isinstance(obj, types.InstanceType):
    do_something()
    else:
    do_others()

    ```
    这样当使用 new style class 时,会执行错误的逻辑,需要修改。所以需要一个相对简单的判断方法...
    yangtukun1412
        7
    yangtukun1412  
    OP
       2015-06-03 10:33:27 +08:00
    原来回复里不支持 md 啊...而且空格的缩进居然也被吃了...
    ruoyu0088
        8
    ruoyu0088  
       2015-06-03 18:33:24 +08:00   ❤️ 1
    把types中的所有类型的id做成一个集合,然后判断你的对象的type的id是否在这个集合之内:

    import types
    builtin_types_id = set(id(obj) for obj in types.__dict__.itervalues() if isinstance(obj, type) and obj is not types.InstanceType)

    is_buildin = lambda obj:id(type(obj)) in builtin_types_id

    assert is_buildin(1)
    assert is_buildin(is_buildin.func_code)
    assert is_buildin(is_buildin.func_closure)
    assert is_buildin(is_buildin)
    assert is_buildin(object())
    assert is_buildin([1,2,3])
    assert is_buildin(types)
    assert is_buildin(list)

    class A(object): pass
    class B: pass

    assert not is_buildin(A())
    assert not is_buildin(B())
    yangtukun1412
        9
    yangtukun1412  
    OP
       2015-06-04 09:55:12 +08:00
    @ruoyu0088

    是的,我也想过遍历 types 模块的方法。目前看来应该是没有更好的解决方案了...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 18:27 · PVG 02:27 · LAX 10:27 · JFK 13:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.