用Python Descriptor弱智了一把

Python Descriptor是个有意思的功能,类似于c++里面的重载operator=和operator T,可以在你访问这个对象的时候,调你定义的__get__(),把返回值作为访问结果,在你给对象赋值的时候,调你的__set__()。 昨晚大约是在搞这么一个类: class Field(object): def __get__(self, obj, objtype): …. def __set__(self, obj, val): ….   class Data: x = Field()   d = Data()class Field(object): def __get__(self, obj, objtype): …. def __set__(self, obj, val): …. class Data: x = Field() d = Data() 然后在访问d.x的时候,没啥问题,__get__被调用了;但是给d.x赋值的时候,__set__没被调用,只是貌似给d搞上了一个域叫x,之后再访问d.x也不会调__get__了…… 在折腾了若干时间之后,最后发现问题特别弱智:Data不是new-style class。只要改成Data(object)就好了……   虽然是我弱智吧,这个语言方面也有问题吧…… 既然old-style class不支持Descriptor,为啥__get__能用__set__却不行…… 而且也没个警告之类……

关于错误信息和bug报告

有时候如果你什么错误信息都不输出,那碰到bug的人会去找相关原因;但是如果你输出了一些错误信息,人们可能会误以为那就是bug的原因。 具体来说,例如这个bug rep: https://bugzilla.mozilla.org/show_bug.cgi?id=833117 简单来说就是很多人碰见了firefox/thunderbird crash。并且他们看见了那么一个错误信息: GLib-CRITICAL **: void g_slice_set_config(GSliceConfig, gint64): assertion `sys_page_size == 0′ failed 然后他们就认为crash是因为这个错误信息引起的。 但其实那个信息只是一个warning,具体来说就是初始化某个组件的时候检查是不是已经初始化过了,如果初始化过了就给个warning并且返回。 所以这些人crash的原因可能各不相同。但是因为看见了一个公共的warning,好多人就跑来”confirm”这个bug了。 如果你啥都不说,或者说这是个warning而不是CRITICAL错误,那多半人们会意识到有别的问题,然后贴stack trace之类,而不是都觉得“我也有这个问题”……