Python技术迷

国企外包突然让离项,说被甲方看见我玩手机,以后就不用来了

国企外包突然让离项,说被甲方看见我玩手机,以后就不用来了

人直接原地离项,连个缓冲都没有。

Image

按理说,就算项目不要你,也该有人把话说明白:谁通知的,原因是什么,后续是回外包公司待岗,还是安排别的项目,工资怎么算,离场手续怎么走。

我的建议是,先把所有沟通都留痕,电话内容转成文字确认一下,问清楚是不是解除劳动关系,还是仅仅项目离场。离场手续没办就更别稀里糊涂签东西。外包公司要是真想甩锅,最怕的就是你开始认真问流程。

算法题:检查是否是类的对象实例

isinstance(x, cls) 这一行代码,平时写业务没啥存在感,但面试题一问“你自己实现一个”,很多人就开始乱了。

最容易写错的地方不是对象判断,而是继承链。

比如:

classAnimal:
pass

classDog(Animal):
pass

dog = Dog()

print(isinstance(dog, Dog))      # True
print(isinstance(dog, Animal))   # True
print(type(dog) is Animal)       # False

第三行就是坑。

type(dog) is Animal 只判断 dog 的直接类型是不是 Animal,它不会往父类上找。可“是不是某个类的实例”,本来就包含继承关系。Dog 继承 Animal,所以 dog 也应该算 Animal 的实例。

这个题如果只写成这样,基本就挂了:

defcheck_instance(obj, cls):
return type(obj) is cls

看着干净,判断也快,但只适合一种情况:必须是这个类本身,子类不算。

真正要处理的,是对象所属类的继承链。Python 里每个类都有一个 __mro__,可以理解为它查找父类的顺序。

print(Dog.__mro__)

输出大概是:

(<class '__main__.Dog'>, <class '__main__.Animal'>, <class 'object'>)

所以手写版本可以这样:

defis_object_instance(obj, target_cls):
ifnot isinstance(target_cls, type):
returnFalse

    real_cls = obj.__class__

for current_cls in real_cls.__mro__:
if current_cls is target_cls:
returnTrue

returnFalse

我一般会先补上 target_cls 的校验,不然有人传个字符串进来,代码还能继续跑一半,后面报错就很烦。

测试一下:

classUser:
pass

classVipUser(User):
pass

classOrder:
pass


vip = VipUser()

print(is_object_instance(vip, VipUser))  # True
print(is_object_instance(vip, User))     # True
print(is_object_instance(vip, object))   # True
print(is_object_instance(vip, Order))    # False
print(is_object_instance(vip, "User"))   # False

这里有个细节,object 也会返回 True。

这不是 bug。Python 里几乎所有普通类最后都会继承到 object,所以 vip 当然也是 object 的实例。这个点不少人会漏掉。

如果题目还要求支持多个候选类,效果跟原生 isinstance(obj, (A, B)) 一样,也不难改:

defis_any_instance(obj, classes):
if isinstance(classes, type):
        classes = (classes,)

ifnot isinstance(classes, tuple):
returnFalse

    obj_mro = obj.__class__.__mro__

for cls in classes:
ifnot isinstance(cls, type):
continue

if cls in obj_mro:
returnTrue

returnFalse

跑一下:

print(is_any_instance(vip, (Order, User)))     # True
print(is_any_instance(vip, (Order, dict)))     # False
print(is_any_instance(vip, User))              # True

这个写法的核心就是一句话:不要只看对象的直接类型,要看它的类继承链。

所以这题其实不难,难的是别被 type(obj) == cls 这种写法骗了。业务里偶尔能用,算法题里一碰继承就露馅。