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

2015-06-02 10:34:34 +08:00
 yangtukun1412

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

class A:
    pass

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

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

2272 次点击
所在节点    Python
9 条回复
knightdf
2015-06-02 15:29:42 +08:00
isinstance(a,A)
yangtukun1412
2015-06-02 17:03:39 +08:00
@knightdf

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

所以在标题里写明了是区分 非builtin 的类
yangtukun1412
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
2015-06-03 10:33:27 +08:00
原来回复里不支持 md 啊...而且空格的缩进居然也被吃了...
ruoyu0088
2015-06-03 18:33:24 +08:00
把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
2015-06-04 09:55:12 +08:00
@ruoyu0088

是的,我也想过遍历 types 模块的方法。目前看来应该是没有更好的解决方案了...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/195466

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX