本文为2022摹客RP原型工具测评大赛一等奖作品
原型设计工具是很多交互设计师以及产品经理都会使用到的,国产原型工具越来越多,给了用户许多选择,而真正满足用户需求的原型设计软件,才是为大家所选择的。作者就摹客RP进行评测,结合实际工作案例,将苏宁智慧屏OS系统中的“自定义频道”功能作为测试案例,从交互设计的角度对产品进行体验测评。
原型设计软件是设计师、产品经理使用频率很高的工具,最早期的软件是Axure,它因为轻量化,功能丰富的特点也一直很受大家追捧,但作为一款国外开发的软件,却也有很多局限性,比如使用者权限,团队协作、购买价格等,正是由于这些因素,让国内很多公司看到了这块市场,纷纷入局,开发相关的软件去竞标Axure;从早期的蓝湖到现如今的各大品牌的原型设计软件,给了项目设计人员更多的选择,大大提高的团队协作效率。
目前我们公司设计团队使用的原型设计工具就是Axure,在实际项目中,团队交互原型的呈现效果很差,统一性不强,组件的复用、新增、修改等同步的效率很低。原型设计样式和规范五花八门,给阅读的人员造成很多不便,尽管团队在每个版本结束之后都会对原型设计的规范进行汇总和要求,但是设计师在进行原型设计时,都习惯了一遍做原型,一遍去比对熟悉规范,都是独自去审查,大大影响了原型设计的统一性;
项目组的设计人员负责的模块都比较独立,绘制原型页面过程中,无法实时同步去协作,绘制结束后还需要保存源文件或者导出html分享给项目组人员,导致Axure的共享协作成本变得非常高。
项目团队想通过引入国内原型设计工具来替代Axure,帮助团队更加高效地进行项目项协作,刚好应邀参加「摹客与人人都是产品经理」联合举办的关于“摹客RP评测文章”的比赛。
所以就想着通过评测这款产品是否在团队中使用和推广,以及通过使用体验提出一些建议,希望自己的拙见和思考能够对摹客RP的产品设计能有一些帮助。本篇文章通过实际工作中的项目,苏宁智慧屏OS系统中的“自定义频道”功能作为测试案例,从交互设计的角度对产品进行体验测评。
测试设备:Macbook pro 2019
测试产品:摹客RP网页端、客户端
测试形式:以实际工作项目为例,对摹客RP的产品功能使用和交互操作进行体验评测
测试用时:四周
测试主要从以下三方面进行:产品的设计框架、产品使用的操作流程、产品的设计组件;框架是产品最底层的基础部分,好的框架会让用户一目了然,比如他的功能是有哪些,功能信息怎么去布局的,信息的层次感有没很有分明,这些都能有效率的让用户阅读和使用产品;操作交互是能让用户对产品体验更直观,如在某一功能的使用流程中,用起来方不方便,交互方式的操作是否顺畅,设计和组件设计决定和产品的“颜值”,设计原则、模式和合理的组件使用能提升产品的价值和表现力,所以本次的测试大纲如下:
第一个角度主要是从设计框架来进行体验,主要包括产品的功能结构、布局的信息层次;两端主页面的框架设计基本是保持一致的,均是左右结构,但还是有很多差异化的细节设计;
网页端拆解图:
客户端拆解图:
(1)左边区域对比
对比可以看出网页端的侧边栏信息更多,有logo,有相关联的工具链接,导航菜单类别多达7个,而客户端侧边栏功能比较简化,只有用户信息和导航菜单,且导航菜单只有5个。
(2)右边区域对比
在内容区上,网页端和客户端的框架是保持一致的,都是顶-中-底三层:
原型设计页面和Axure的页面相似度很高,大致可以拆分成四大部分:标题和工具栏,左边功能区分上下两层,可以上下收缩拉伸,中间是原型设计区域,右边设置面板区主要属性、交互、备注三个主要功能。页面的布局符合设计师使用习惯,理解成本很低;网页端和客户端的也是统一的。
整体来说,两端的控制台主页面满足了设计师基本的使用需求,布局中规中矩,但两端细节差异还是有很多的,虽然是不影响用户正常使用,但在实际操作中,设计师需要花很多时间来适应两端页面和操作的差异,所以在产品评测过程中一直疑虑:同一套信息和内容,为什么要做两套控制台页面样式来增加设计师的学习和使用成本呢?信息内容布局的差异化会影响设计师能否快速熟悉功能,操作的差异化会影响设计师的体验感。
为了验证统一性的重要性,我找了市面上主流的设计工具做了对比,如下图,在多端统一性上(忽略极小的差异化细节),他们的共有率达到了100%,所以足以证明这些产品对统一性的重视程度。
关于操作台页面统一性的优化方案如下所示:
优化点1:两端的主页面侧边栏的信息框架可以保持一致,首先是logo、用户账号信息的位置;其次是导航菜单的数量,可以让用户在两端之间切换使用时,通过统一性加强用户对界面的理解
优化点2:两端的右边操作区域针对项目和项目集的管理和筛选,展示方式的多样性应该保持同步,包括配置筛选条件也可以同步;
优化点3:两端关于全部菜单的功能框架的设计,可以在多级菜单(全部>项目集1>项目集2)和一级菜单(全部)中二选一,复用一种设计样式,降低开发成本;
优化点4:两端关于“设计团队的切换”的设计,网页端点击团队名称出下拉菜单,进行团队切换,客户端点击侧边栏的用户名,出现次联菜单,再找到团队切换列表,两端可以在组件使用和入口方式的设计上统一,保证信息内容、位置的统一性的前提下,使用可复用的设计样式,降低开发成本。
原型设计页面,功能很全面,使用起来很便捷,整理了如下优缺点:
爽点1:如文字元素的属性设置点非常多,英文大小写,首航缩进等,可设置的参数很多;
爽点2:支持画板响应式布局,选中画板作为对象时,可以在属性面板中进行删除;
爽点3:可以创建项目资源库,包括颜色、文本、组件等设计资源,设计更加高效;
问题点1:相对应的属性列表展开显示后,模块空间的没有充分利用;如圆角这个参数可以选择百分比的样式,就需要另起一行;
优化方案1:属性面板可以保留比较常用的属性参数,新增加的参数设计如果不常用会占据空间,且在黑色色彩模式下,信息的阅读效率会收到影响
问题点2:右边整块属性面板不支持自适应拉伸,位置是固定的,如元素透明度这个参数为100%时,数字也不能够显示全。
优化方案2:属性面板增加自适应收缩,会让页面空间更加灵活。
第二个角度主要是从相关功能的操作使用流程作为切入点去体验,主要7大核心流程和14个操作小任务。
任务1:在控制台页面找到功能的入口,新建一个名为“自定义频道”的项目和两个名为“Biuos1.0”、“苏宁智能终端”的项目集
客户端操作示例:在首页菜单,有个单独项目编辑区域,可以直接点击进行命名和选择尺寸。在其他菜单下,如果有创建按钮,均可以点击,页面中间会跳出弹窗,直接对项目和项目集进行创建编辑。
网页端操作示例:在相关的菜单中,只要有创键按钮,就可以进行创建编辑,仅支持点击按钮-跳出弹窗的途径。
设计爽点1:在客户端,有个很大的项目创建区域,用户可以命名,选择尺寸,很直观,增加了项目创建的入口;
设计爽点2:网页端可以创建项目和项目集,客户端只能创建项目,虽然没有统一,但是从使用习惯的角度思考,这个设计还是非常好的,项目集是比项目要大的,根据设计师使用习惯,考虑到网页端的网络链接,大多数用户都会下载客户端去操作,并且当项目责任人建立好项目集,负责相关模块的设计师就可以专注在项目上,避免了乱建项目集,造成混乱;
体验问题1:两端的很多基础导航菜基本都有新建项目或新建项目集按钮,考虑到用户在切换不同菜单时,都能提供这个入口,虽然能方便用户操作,但有一些过度引导;
优化方案1:减少过度设计,菜单应匹配相对应的信息需求。例如用户切到我的收藏菜单,需求就是去查看收藏项目,新建项目就是非必要的选择,加上就会变的强行引导;
体验问题2:在创建项目时,通过弹窗的方式去进行创建编辑,这样会让操作流程变得复杂,而且弹窗中的信息优先级不高,创建结束后也都可以修改;
优化方案2:模态弹窗对用户的干扰程度很高,创建项目应该是比较简单的操作,不需要强干扰的组件去提示用户,建议可以直接过度到原型设计界面。
任务2:在控制台页面,把项目“自定义频道”移动归类到“Biuos1.0”的项目集
客户端操作示例:项目和项目集仅有列表的展示方式,将项目“自定义频道”移动至项目集“Biuos1.0”时,需要点击项目中的操作按钮,弹出操作列表,选择移动,跳出弹窗,选择项目集确认,无二次弹窗确认。
网页端操作示例:项目和项目集有列表和宫格两种展示方式,将项目“自定义频道”移动至项目集“Biuos1.0”时,需要点击项目中的操作按钮,弹出操作列表,选择移动,跳出弹窗,选择项目集确认,再弹出弹窗二次确认。
体验问题1:网页端和客户端移动项目的过程中,第一次都需要有弹窗,选择项目集分类,但下一步的操作,网页端使用模态弹窗让用户二次确认,确认移动成功后有提示。客户端成功移动成功后,没有提示。
优化方案1:结合两端的优缺点,首先网页端避免使用确认移动的二次弹窗,减少操作流程,客户端移动成功后,增加操作提示,提升交互感知。
体验问题2:项目或项目集不可以直接拖拽进行移动管理操作,只能通过按钮点击选择移动选项才能操作,操作比较迟缓。
优化方案2:为移动操作增加鼠标拖拽功能,更加快速的进行项目归类,效率高。
任务4:选中原型设计页面的左边功能区的【页面】tab,为“自定义频道”功能创建若干个页面,随机对页面进行设置操作(创建、重命名、移动、复制、删除、撤销删除)
操作示例:点击「添加」按钮,可以进行页面创建,选中任一页面,右击出现弹框,进行选择重命名、移动、复制、删除等操作;双击页面标题都可以进行页面名修改,拖拽页面可以进行运动归类,选中页面点击设备删除键,出现弹窗提示是否删除。删除后,设备无快捷键撤销删功能。
新建和复制新页面后,新页面变为当前页面,且有背景底色,但无法使用设备删除键直接进行删除操作,需再次点击选中新页面,让文字变为纯白色,才可以删除文件。
体验问题1:页面删除后没有进行删除撤销的快捷键“command+z”操作,“撤销”快捷键是设计师最常用且依赖度很高的操作。
优化方案1:增加“撤销”快捷键的使用。
任务5:选中原型设计页面的左边功能区的【页面】tab,使用回收站功能、将“某一页面”删除再从找回
操作示例:选中某一页面,进行删除操作确认,点击回收站按钮,开始回收模式,找到分页面,鼠标悬停在页面上,显示恢复和删除按钮,点击恢复按钮,再弹窗确认,页面恢复。退出回收站模式,才能显示当前所有页面。
设计爽点1:增加“回收站“模式,用户可以找回页面,扩大了容错范围;
体验问题1:回收站模式退出的按钮样式和工具栏的撤销重合度高,易混淆;其次这里的回收站模式需要开始和关闭两种状态,整个过程中需要2次点击操作。
优化方案1:回收站对应的是页面,单独再加一个tab对于信息内容切换会更便捷,省去“回收站”,模式开启和关闭的流程。
任务6:选中原型设计页面的左边功能区的【页面】tab,选择“自定义标签”页面,切换到【图层】tab,对页面中的“默认状态”画板中的图层进行顺序调整
操作示例:选中画板其中一个图层,然后移动到另一个图层的上方或下方,调整图层顺序,但不能进行拖拽移动,只有置于顶层和底层的按钮操作。
体验问题1:设计师在制作原型图时,需要调整画板中的图层顺序,置顶或置底的操作不能解决使用者调整图层顺序的效率问题,移动拖拽能灵活快速的给图层排序。
优化方案1:增加鼠标拖拽移动功能,让图层位置的移动更加方便。
任务7:在“自定义标签”页面编辑区进行画板的创建、设备和尺寸选择、复制、命名、属性设置
操作示例:工具栏中使用“添加辅助画板”或者快捷键A创建画板,在原型编辑区域左下角可以进行进行设备和尺寸选择、使用快捷键command+c/v、直接双击画板标题可以进行重命名、选中画板后,在右侧功能区域调整参数进行属性设置。
设计爽点1:可直接在视图中双击画板名称文字,直接选中进行修改,不用在图层页面找对应页面进行名称修改,图层的空间有限,当画板数量超过之后,就需要上下移动来回审查,所以这个设计细节让操作更加聚焦,对于大批量的画板名称修改,很节省时间。
体验问题1:画板设备和尺寸选择的优先级高于画板快捷创建,通过鼠标悬停的操作方式呼出多级菜单分类,交互的可控性比较差。
优化方案1:类比市面上其他产品,基本都是快捷键A调出设备尺寸选择,而且大多是在属性面板使用列表下拉的方式展示。快捷键“A”的使用对象可以重新定义,加强快捷创建画板的优先级,重新设计画板设备和尺寸选择的位置和交互出现方式。
体验问题2:在复制画板时,不支持选中画板后,使用“option+鼠标键”快捷操作进行复制拖拽,新画板不能任意的拖拽到自己想要的位置。
优化方案2:增加快捷键的使用。
任务8:在“自定义标签”页面的画板中利用工具绘制低保真设计稿,设置元素属性
操作示例:选中自定义页面,在默认状态的画板中对元素文字、形状、颜色等属性参数进行设置。
例1:在画板中缩放矩形,设置面板中的宽高参数没有变化;
例2:在属性中将初始矩形外边框宽度值从“1”变为“2”,但页面中元素没有变化,仍然是1,只能在点击非宽度的参数任意区域后,宽度数值的变化在页面中才能响应;
操作示例:将图片拖入某画板内,图片位置在画版的顶部位置,当将画板拖去来,在左边功能区的图层tab中,图片还在原来画板顶部显示,拖动画版,图片在画版外和画板一起移动。
体验问题1:两个例子都是属性面板和画板联动无响应的问题,不管是画板中的元素联动属性面板的参数,还是属性参数联动画板中的元素,都没有实时响应。尤其是外边框的宽度值无法实时显示,这就对设计的效果很难把控。
体验问题2:图片拖进和拖出画板时,图片图层的归属不清晰。
优化方案:这两个槽点属于产品的性能问题,可针对性能这个点,加强优化。
任务9:在“自定义标签”页面的画板中查看元素与元素,元素与画板,画板与画板的距离,进行元素和画板的距离调整
使用鼠标和键盘键可以查看“默认状态”画板中元素的间隔、与相邻画板的间隔,在悬停展示间距的同时去调整位置距离。
体验问题1:只能查看同一个画板中元素之间的距离,无法查看画板之间的距离,且同画板中不能在显示距离间隔的状态下,对元素位置进行调节。
优化方案1:增加设计优化,完善距离相关的测量和位置移动的操作问题,提升设计体验和用户的原型设计效率
任务10:在“流程图”页面中使用流程模式,为“自定义频道”功能绘制逻辑流程图
操作示例:在「流程图」页面,在工具栏中打开流程图模式,为“自定义标签”功能画一个简单的逻辑流程图,梳理业务流转的逻辑关系。
设计爽点1:产品内置了很多流程图组件,当鼠标获取矩形元素的连接线端点后,开始移动至松开鼠标结束,流程组件库弹窗会自动出现,可以选择对应的矩形组件。并且制作好摹客RP源文件可以和自带的PRD文档工具相关联,选择带有流程图内容的画板,直接转化成图片导入到文档中,这个联动做的相当给力。
任务11:对“自定义频道”功能的原型项目进行保存
操作示例:当设计结束或中断时进行项目保存时,可以使用保存按钮或者快捷键“command+s”对项目进行保存。
体验问题1:当用户保存后,页面并无明显的关于“项目已经被保存或者可以实时进行保存项目”的提示;
优化方案1:首先用户不知道的项目保存的时效性,可以使用“Toast”提示用户。
任务12:为“自定义频道”功能页面的跳转和设置保存创建页面交互事件
操作示例:在当前频道有内容的场景下,开启调整模式,移动频道顺序,再次确认频道,移动跳到频道显示或隐藏功能区域,为频道自定义设置创建交互事件,最后使用弹窗对频道顺序调整、显示、隐藏这些操作进行数据保存;在右边功能区的选择“交互”菜单点击「添加交互」按钮,对事件属性参数进行设置。
设计爽点1:在使用Axure原型工具时,通常一个页面我们会使用文字描述主要信息和交互操作;例如,在自定义频道设计的页面主要就是标题、频道名称以及状态图标,这是显性化的信息。
对应保存的的操作还有各种隐性信息和操作,比如设置保存的弹窗,不可操作的提示、网络异常的提示等;我们会使用很多静态页面去描述隐形信息和操作。但摹客RP的原型工具支持的主辅画板的模式,可直接设计交互转场、提示等隐形操作,更直观的呈现原型设计效果。
任务13:使用播放功能或进入摹客协作模式预览“自定义频道”原型设计和交互效果
操作示例:在工具栏点击播放按钮,预览“自定义频道”功能的原型设计和交互点击效果;点击发布,进行项目分类,进入慕客协作网页端查看所有页面和画板以及交互效果。
体验问题1:单独演示预览时,视图窗口只展示页面,不展示页面内的画板;在慕客协作网页端可以进行查看所有内容,当使用网页端查看画板内容的过程中,有多次无法快速找到「画板」入口的场景,查看画板的入口不是很容易被注意到。
优化方案1:演示预览状态下,增加“查看画板”的入口,在慕客协作的网页端强化“查看画板”的入口
任务14:发送项目或项目集链接邀请协作人,协作者点开链接进入原型设计页面
操作实例:在操控台找到“自定义标签”的项目,点击按钮找到「成员管理」,跳出弹窗,复制链接,发给协作人,协作者点开链接进入页面协作
体验问题1:项目管理人分享项目链接给协作者,协作者点击链接直接进入原型设计页面进行操作编辑,在网页端从原型设计页面返回到操作台页面后,再点击项目,无法进入原型设计页面;客户端可以正常操作。
优化方案1:打开网页端重新进入页面的权限,让用户能够自由进入或退出页面。
这部分通过最常用的7个交互操作,建立以目标为中心的体验流程,再细分出了14个操作任务对产品进行体验说明。操作体验主要聚焦在统一性、功能设计、交互操作效率、细节设计。首先在任务流程中体验到的爽点设计,体验是非常不错的,其次是针对相关的一些设计问题也有描述并提出自己的优化建议。
第三个角度主要是从设计组件来进行体验,这部分内容主要有如下6个体验点组成。
网页端和客户端对于导航菜单(“全部”)组件的结构不一致,网页端的全部菜单下会展示二级菜单,客户端没有;两端菜单数量都不相同;
优化建议:导航菜单组件结构和数量统一。
优化建议:两端的页面相同图标需要保持一致,包括类型,样式,统一性,减少差异化,关于图标设计表意要传达精准一点。
新建项目和新建项目集是产品的两个重要功能,从功能重要程度来说应该是要保持一致的,目前设计明显是新建项目的优先级高于新建项目集,虽然都是用“图标+文字”的按钮样式,但图标的样式过于简单,且新建文件使用强提示的高亮底色,更能吸引注意力。
竞品中,如蓝湖、即时设计、Figma、Pisxo的功能和摹客RP一样都有新建文件(项目)和新建文件夹(项目集)功能,竞品基本都保持相同的设计样式,保证功能优先级是一样的,仅有mastergo虽然按钮和摹客RP一样使用强提示按钮,但它的功能框架设计和摹客RP不一样。
它创建文件夹的功能放在左边菜单的创建团队中,新建文件的按钮和文件导入是独立的,虽然设计样式不一样,新建按钮也相对突出了,文件导入的按钮还有动画效果。
优化建议:可借鉴主流的原型工具类的设计方案,平衡功能的优先级,在图标设计样式上让功能更加形象。
(1)弹窗样式设计的统一性,如新建和删除项目或项目集时的弹窗按钮,它并不是特殊使用场景,都仅需要“确认”和“取消”简单操作,但是鼠标悬停文字按钮上的样式是不一样的。一种是加浅灰底色,文字没变化,另一种是改变字体的透明度。
(2)多次弹窗增加了操作流程,如网页端项目移动时,会有二次弹窗确认。
优化建议:弹窗的按钮设计样式上可以保持一致,对于产品中的个别功能的操作,建议少用或慎用弹窗组件,缩短操作流程。
(1)文件界面的左边功能区的“图层”菜单中包含画板和图层信息,这个标题名称和内容不对应,表述不精准。
(2)页面删除的弹窗提示文案没有给出完整且能防错的的提示,弹窗只提示是否删除当前页面,并没有提示用户如何找回和被删除文件的去向。
如下例子为操控台项目删除和原型设计的页面删除:项目删除的文案:“确定将此次项目加入回收站”,页面删除的文案:“确定要删除当前页面吗?”
(3)新建项目和新建项目集两个按钮的文案表意不精准,改为“文件和文件夹”,这样的表述更简单明了。
(4)导航收藏菜单名称不一致,网页端用“收藏”,客户端用“我的收藏”,可以统一为“我的收藏”。
优化建议:关于文案部分,主要包括菜单栏、图标、按钮、弹窗提示文字等应用场景,进行修改完善。
产品的主色调很深,没有浅色色彩模式可以切换,同类的主流产品基本都是默认浅色,如即时设计、Masetrgo、Pisxo等都以默认浅色界面,Figma更是支持浅色深色切换;
优化建议:因为用户对颜色的接受和敏感度都不一样,提供深浅色两种颜色模式进行切换,可以在界面色彩运用上满足不同使用者的需求,若不提供,建议浅色模式,白色在感官上更加干净、整洁。
设计和组件主题包括6个部分,这些在产品评测,是很容易被注意的设计点,也是产品最基础的组成元素;它的设计呈现决定了用户的好感度,好的设计是需要通过这些元素来表达它的设计原则和理念;组件的设计和使用也是要合理和克制的;例如导航菜单和图标设计应该在网页端和客户端保持一致;文案表述的应该精准、简单、明了;按钮和弹窗设计也可以再克制一点,色彩模式需要干净简洁,最大程度的减少对用户的干扰,提升用户的粘性。
以上就是四周产品测试总结分享了,这篇测评文章主要是从交互的三个角度:页面框架、页面操作流程、页面组件设计,通过深度使用和体验这款产品,从中提炼出一些想法和建议,这里就个人使用体验做出以下终结。
摹客RP这款原型设计工具与视觉、产品的关联性方面设计的很好:作为一款原型设计软件,它的功能很丰富,覆盖了设计师做原型设计的大部分场景,能利用视觉思维发挥产品优势,在项目协作,横向和产品相关的工作内容进行关联。
这一点在产品体验中感觉是十分明显的,设计工具软件,基本都有网页端和客户端的,控制台页面都不会进行差异化设计,所以当第一次在不同端打开摹客RP控制台页面时,呈现出的是不一样的内容,我的第一印象是:有这么多不一样的地方啊,我要花点时间再看看对比下?我刚才的那些操作入口在哪里啊?
在交互操作上产品要有畅通感,即操作起来够舒服,能够给予操作有效提示,能够在进行任务操作时有效率;
在摹客RP体验过程中,注意到很多设计细节,有很多不错的地方,也有很多需要优化完善的设计点,如下所述;
第二点产品性能问题,很多交互操作过度不自然,转场太快,无状态结果的反馈,操作生硬;还有原型设计画板、元素和属性面板参数的联动很差;第三点是项目原型设计中的关于元素相关的设计点,包括图片的图层归属问题,距离的测量等。
总的来说摹客RP是一款比较专业且实用性很强的的设计协作软件,他基本兼容了原型设计软件“Axure”的大部分功能,也适合团队协作中进行使用和推广,但随着市面上的竞品越来越多,后续的竞争推广也会越演越烈,所以个人认为产品应该做好以下两点,会增加自己产品的优势;首先工具可以轻量化,注重常用功能的用户体验和产品的性能优化。
其次作为一款设计协作软件,面向的是广大设计师,产品细节方面的问题特别容易被设计师捕捉。所以需要着重把控这两点,进行积极的推广助力,才好抓住设计的心!这里也祝摹客系产品能越做越好!
本文为2022摹客RP原型工具测评大赛的测评文章,如对摹客RP感兴趣可点击体验链接:https://www.mockplus.cn/rp-event/?hmsr=woshipmqianwei
本文由 @Q什伍 原创发布于人人都是产品经理,未经作者许可,禁止转载。
题图来自 Unsplash,基于CC0协议。
该文观点仅代表作者本人,人人都是产品经理平台仅提供信息存储空间服务。
辑导语:对于团队产品知识库产品,想必大家都不陌生,但是很少有人能够系统地去管理自己的知识。因此,作者思考了关于团队知识管理的四个问题,并对市场上的知识库产品进行了比对,与大家分享,希望对大家有所帮助。
知识管理相信大家并不陌生,但我在身边简单调研一圈之后发现,大部分人没有系统的去管理自己的知识。在工作之余的阅读过程中,我接触到卢曼的卡片笔记法,接触到obsidian、Notion,并且尝试构建自己的知识外脑。
个人知识管理我们后面可以单独有一篇文章详细阐述。今天想聊一下团队知识管理,在经历了很多次找历史资料找不到的痛苦之后,我决心要打造一个团队共有的知识库系统。一方面提升团队效率,一方面避免重复工作。
为此,我主要思考了四个问题,并且比对了市场上知识库产品,和大家分享一下,供大家参考。
团队知识管理这一概念很少单独拎出来说,目前团队知识管理经常和文档管理产品、协同办公产品耦合在一起。由于很难找到纯粹知识管理的行业报告,我们可以看一下市场上的文档管理赛道的玩家。
文档管理产品图谱,图源:甲子光年
这份甲子的报告里并不完全全面。除了上面列举的部分文档管理产品可以划在知识管理产品范围内,还有包括一些新晋的知名玩家,比如钉钉文档的团队空间、飞书文档的知识库、海外的知名产品Notion、Confluence等。
知识库产品百度指数
我们可以看一下百度指数,知识库这个概念非常少有人索引,而在知识库产品里,石墨文档相对热度最高。
我们可以粗略的统计一下知识管理的市场。根据艾瑞咨询的研究报告,2020年国内协同办公市场是440亿元,一直以来爆火的短视频去年国内市场规模是1300亿左右,这样对比大家可以感受一下协同办公的市场具体有多大。
而协同办公产品包含:文档协同、企业网盘、项目协同、会议系统、OA协同平台等等。知识管理只是协同办公的非常小一部分的市场。这样我们能进一步感受到知识管理的市场规模其实真的不大。
客户通常都知道知识管理很重要,但只有在他们遇到:明知道某个历史档案能解决他们眼前问题,但就是找不到这个资料的时候。他们才会对整理团队知识有更感性的认识,或者说更痛的领悟。
我看下来管理知识困难主要有几点原因:
首先,知识的创造困难。
创造知识的过程是反人性的,这是不能看到即时反馈的一件事。大部分团队成员不爱写总结文档,工作也许可以干的很漂亮,但留下的东西非常的少。因为从工作的角度,项目交付完了,客户或者用户满意了,在团队成员心里就算了事了,文档整理工作在他们心里属于分外之事。
其次,知识的维护困难。
维护团队资料的过程是对抗熵增的过程。熵增指的是:在一个封闭空间内,事物会走向混乱和无序,并且不可逆。就比如一个仓库如果没有人管理,一定会越来越乱。
团队知识库也是一样。传统的文档管理流于表面,企业也许会有自己的资料库,但很可能“XX项目文档”文件夹下完全就是空的。按项目管理知识里的说法,就是没有维护好组织过程资产。
知乎上经典好文里经常出现这样一句评论:躺在我的收藏夹里吃灰去吧。大家看到好东西,第一反应会把他们收集起来,但维护和利用就非常少了。
最后,知识的快速查找和调用困难。
当知识库内容不全,陈旧无效,搜索的结果不精准,无法导出转发,这些都会极大打击我们使用知识库的热情。我们发现知识库存在但无法提升我们的工作效率时,这个知识库基本就算失败了。
市场上的知识库产品,能不能帮助团队管理好知识呢?
我选择几种知识库产品,从6个功能维度去对比市场上的知识库产品。我认为好的知识库产品这六方面都需要相对出色:工具、模板、协同、安全、搜索、导出。
我们前面说了,创造知识困难。作为团队知识库,首先要解决的是内容的输入。内容的来源有两种:即时创造和外部迁移。
即时创造面向的是新知识。主要考量的是知识库产品编辑器能力。如果能让用户更简单便捷的编辑文字,编辑器工具属性能让用户感觉到爽的话,无疑是会提升用户的创造意愿的。
外部迁移指的是陈旧知识或者历史资料。主要是能支持历史数据的迁移进入知识库。
我们先看各家即时创造的能力,也就是产品编辑器能力。
(1)页面布局
钉钉的编辑器和传统的word编辑器布局类似,功能区出现在编辑器上方,由于大部分人都长期使用微软的Word,这种布局符合用户习惯。
图中绿色部分可以看到钉钉的文档支持部分的块状编辑。块状编辑最大的好处是结构的灵活,便于用户调整文档前后文结构。
钉钉可能是为了满足不同用户编辑体验,在功能栏右侧设计了缩进按钮,缩进之后保留核心功能在功能栏,这样可以营造更简洁的页面。
钉钉文档
如果说简洁画风,石墨文档可以单独拿出来。石墨的整体页面简约直接,按钮加了阴影,整体是灰色系的性冷淡风。支持创建传统文档和文档。石墨文档页面看下来让人觉得舒适,中间的功能栏没有影响到整体的整洁简约的体验。
石墨文档
而飞书、Notion、Confluence的布局就脱离了微软系的画风。特别是作为口碑非常好的Notion,几乎是一个全新的编辑界面。Notion是非常明显的块状编辑,所有的板块依托块状组件化呈现,同时页面风格灵动,和目前大部分文档产品截然不同。
Notion
飞书和Notion一样完全支持块状编辑,而Confluence并未使用块状编辑。页面布局的创新可以给用户带来新鲜感,但对于习惯了微软Word的用户来说,也许会反而有一些阻碍。
百度俞军说过,产品价值=(新体验 – 旧体验) – 替换成本。编辑器页面作为最直观的窗口,这部分的颠覆一定会带来较高的替换成本。
Confluence
飞书输入方式石墨文档和钉钉将整个功能区列在主屏上方,无疑是能让用户所见即所得的处理文档。
我们一系列常用的标题、对齐、插入、字体选择等功能可以一键触达,同时也支持Markdown编辑输入。他们的做法是,同时支持传统文档和新式文档。传统文档的输入和微软Word的输入方式保持一致,新式文档的输入则是块状编辑加上支持Markdown输入。
而对于Notion、Confluence、飞书这几款产品,编辑页面会做更简洁,但非常依赖Markdown编辑,这就需要用户去熟悉Markdown的编辑语法。
对于程序员群体来说,相信这是一个他们非常热爱的输入方式,但是对于大部分用户来说,相信这还是一个相对新的概念。
Markdown输入最大的好处就在于,你在码字编辑文档的时候,不需要移开右手去点击鼠标。毫无疑问这可以提升输入效率,但是提高了准入门槛。
插入功能插入这个功能,同样是每个产品都引入的。我们可以非常直观的对比各家的优劣。
通常我们在word编辑器里常用的是插入图片、表格。新一代的知识管理产品在插入功能上做的都很好,比如钉钉除了支持常规的图片、表格,还支持脑图、原型图、代码块等等。
(2)外部文件导入
在知识库管理的过程中,我们一定会存在一些老文档需要入库。
Notion目前支持12种类型文件,其中包括竞争对手印象笔记和Confluence。
石墨文档和飞书支持本地文件夹上传,简单粗暴,看起来很好用,但本质是起到网盘的作用,并不利于用户管理。
而钉钉目前仅支持word和excel的导入,以及文件夹打包上传,Confluence只支持word和google文档。对于工具部分,我们用一个表格总结一下。
单从产品编辑的能力上看,目前钉钉的文档编辑能力页面最接近office用户的使用习惯,基本能满足图片、原型图、设计稿、脑图、表格等常用功能的插入,同时也兼顾Markdown的编辑方式。
但从外部导入文件的能力依然需要继续提升,目前支持Word和Excel文件导入,以及支持文件夹打包上传。
飞书走的路线是依赖Markdown编辑方式,这对于从Office用户引流可能会有一些困难,并且对外部导入文件的能力也需要提升,飞书支持的是文件和文件夹上传,这种方式非常便捷。
但从知识管理的角度看只完成了其中的收集功能,知识管理除了收集应该还有科学命名,文件筛选入库等等功能需要设计。
石墨文档和Confluence的编辑体验和阅读体验很好,基础的编辑功能很完善,但在功能创新方面还略显不足,同时在文件导入方面都需要进行提升。
Notion在产品编辑能力这一项上综合看相对完善,无论是编辑能力还是迁移导入的能力都很优秀,对于习惯使用块状编辑和Markdown输入的用户,Notion可以说领先其他产品半个身位。
为了帮助用户更好的创造知识,除了有满足用户体验的设计器产品,我期待的是还需要有加速用户创作的文档模板,并且模板质量要高。目前模板功能也是各家都有的,我们对比来看。
飞书和钉钉的产品模板分为两部分:知识库模板和文档模板。
钉钉模板
两个产品支持创建不同属性的团队空间或者知识库,并且团队空间里为用户整理好了对应模板,除此之外,二者支持新建文档时候以模板的形式创建。
值得一提的是,飞书的模板能支持类似Airtable的多维表格,这和他的块状编辑能力密不可分,这样一来飞书模板的灵活性会更大。石墨文档、Notion和Confluence只支持文档模板创建。
Confluence模板
Notion模板
在模板这一层面,各家产品看下来基本都能满足用户需求。
飞书和钉钉的知识库空间模板的预整理能让用户更好的上手。而Notion和Confluence在模板的处理上会有更多的灵活度。特别是Notion对Airtable的集成,能让用户在一个文档上玩出很多花样。
到了协同层面,我们考虑的是团队成员如何更好的维护知识库,这一点上协同办公平台具有天然优势。
协同主要分为两步:
第一步是组建知识库团队。
在第一步,钉钉和飞书就凭借办公产品的属性跑在前面,这两者可以直接打通内部团队通讯录,简单便捷的把知识库团队成员组建好。而Notion、Confluence、石墨则是需要通过邮件邀请其他人加入团队。
第二步是知识库团队共同维护知识库。
比如,知识库内容的删改都被记录,支持评论互动等。这样能更好的让大家参与到知识库的建设中。
钉钉支持知识库内@团队成员,支持段落和划线评论,同时能够把钉钉内部群聊链接导入到知识库文档里。这在一部分飞书和钉钉二者的功能类似。
关于这部分功能,目前二者都只是加了群链接的跳转。而我相信更有沉淀价值的可能是群聊里的某段聊天记录。目前二者在这处理的都有点粗糙。
钉钉额外考虑到的是,在团队空间里能够插入项目进度,这可以及时和项目保持协同联动。而飞书在协同的部分,考虑的是支持插入日程和投票。
Notion、Confluence、石墨文档三者承载的OA功能比较少,基本只能在知识库空间范围内和队友互动。
但是不代表这些产品没有考虑协同的问题,Notion和Confluence能够进入Slack生态,Slack是目前和微软Teams竞争的办公产品,在全球有非常不错的用户基础。Notion和Confluence能够依托Slack弥补协同的短板。
石墨文档同样集成在钉钉生态,能够从钉钉生态直接访问,也也加强了石墨文档的协同能力。
但总体来说飞书和钉钉,依托用户数和OA系统,形成相对完善的产品矩阵,能够更大价值的发挥协同作用。而Notion、石墨文档、Confluence在知识库的特性上更纯粹,协同能力会稍弱一些。
对于文档安全方面,我考虑的是知识库内容的创建、查阅、转发需要有权限系统进行约束。一方面能保证团队信息安全,一方面能更好的保证知识库内容的质量。
Notion和Confluence的安全模块作为付费内容没有办法体验,可以看到产品设计也是考虑了文档安全因素的。而石墨文档在知识安全上考虑并不是很完全,仅支持空间权限设置,这也是石墨文档需要提升的。
钉钉和飞书同为协同办公产品,在安全能力上是优于纯知识库产品的。目前飞书限制导出、打印、创建副本和复制。钉钉支持访客水印、限制复制、私密文档、权限继承等。二者都在文档安全上有自己的思考。
关于安全这部分,Notion、Confluence和石墨文档都需要再深入思考一下。
对搜索部分的期待主要就是搜的准,支持自定义的搜索。毫无疑问搜索能够帮助用户更好的使用知识库。
这里我们就要说一下为什么不要用PC本地做知识管理,因为文档内部的内容是完全无法检索到的,这样的检索能力相对就弱很多了。而目前知识库产品大部分是可以同时检索标题和内容的。
飞书搜索
钉钉搜索
石墨文档搜索
Notion搜索
Confluence搜索
可以看到知识库产品对于空间内文档搜索能力不错。而且搜索精度也能满足使用需求。
在搜索的筛选规则上,石墨文档、飞书、Noiton、Confluence都支持更为细节的筛选,比如根据创建时间、文档类型、修改时间等进行搜索。
目前钉钉团队空间的搜索准确度很高,筛选规则的功能设计偏少。而让人感觉不一样的地方是,针对文档索引,钉钉采用了其他产品没有的首页辅助脑图架构的方式管理文档,以便用户更快索引和知识记忆。
在新建知识库的过程中,知识库会自动生成知识库首页,知识库文件的标题名会自动生成思维导图出现在首页里。同时给脑图加了跳转链接,这个设计很独特。
钉钉团队空间首页
最后一个环节,导出。知识库的文档经常会碰到需要导出转发的场景,比如导出一份合同去签署,如果导出的类型受限,导出的格式混乱的话,这肯定是不能接受的。
从导出这一功能看,能够导出PDF和Word这两类常见文件,产品基本就合格了。目前知识库产品都能基本满足需求。
我们在各家产品综合能力上做一个总结。
钉钉的团队空间产品形态兼顾创新和兼容,更符合微软Office用户的编辑习惯,这样带来的好处是能够更平滑的将用户从微软Office引流。
其次,钉钉的办公工具属性可以与知识管理更好地融合,以文档为核心天然形成知识库,钉钉的团队空间能减小协同的障碍,日常聊天记录里的工作文档,可以快速的转入团队空间进行管理。
并且钉钉团队空间对知识库内知识安全考虑的更为细致,能够让人放心的保证团队知识的私密性。作为目前在线组织数最多的办公产品,可以感受得到钉钉在协同办公上的深厚积累,对知识库建设来说是强大助力,对于其他产品来说也是不小的压力。
Notion是可玩性非常高的产品,all-in-one的理念也圈粉不少用户。Notion的块状编辑和丰富的插入组件俨然是很多同类产品模仿的对象,可拖拽的块状编辑让页面非常的灵动,支持Airtable式的表格插入更是为产品拓展了表格能力。
但是用好Notion是需要一定极客精神的,Notion更像是少数派的效率工具,而不是普适的文档管理工具。纯粹地把Notion当成Word用会让人觉得非常浪费这个产品。
而Notion非常依赖Slack补充他的协同能力,这就需要Notion和Slack同时非常优秀,才有更大的竞争力。
目前Notion只支持英文和韩文,网上有一些非官方汉化方式,在一些语言细节处理上还有一些问题。Notion如果完全汉化,并且做好教程,绑定协同办公平台的话,对本土的文档、知识库产品一定会带来较大冲击。
飞书的知识库在编辑上依赖Markdown编辑,并且有一些块状设计和Notion是趋同的,可以看到产品设计的过程是想要改变用户输入习惯的。
出身于办公系统的飞书知识库,在安全性上做了一定的考虑,而在知识库搜索功能上,飞书看起来考虑的也很深入。对于钉钉和飞书这两个协同办公产品来说,自成生态的建设知识库一定是最简单高效的。
Confluence可以说是纯知识库产品的代表,编辑页面简洁,功能相对丰富。知识库生态组件完善。
然而,和Notion一样,全英文模板绝对会把一大部分人挡在门外。然后网页打开时间较长,这也是一个不利因素。
石墨文档的页面风格是让人蛮喜欢的,当然这个相对主观,也不保证会不会时间长看了觉得略微单调。
从产品实用性来说,石墨文档一直稳扎稳打有着比较好的应用基础。对于视频、地图的直接集成可以极大的提升阅读体验,让人惊喜的一键回溯功能可以做好版本管理,不得不说石墨文档在产品细节上是花了心思的,百度指数相对最高也说明了石墨文档产品口碑。但插入的组件类型不足,会让人稍感缺憾。
创建团队空间,管理团队知识库在我眼里是很重要的一件事,也是一件难而正确的事。我们要怎么才能在内部用好知识库产品。
我们在前面介绍了各家产品能力,如果团队成员都很Geek,对新鲜事物有探索的好奇心,可以考虑使用Notion。
如果团队成员更稳健一些,并且已经在公司内部使用了钉钉、飞书这类产品,毫无疑问,用钉钉的团队空间和飞书的知识库更合适。
如果对知识管理和协同办公的交集很小的话,石墨文档和confluence作为非常专业的知识库产品也是很好的选择。
Notion和Confluence是海外的产品,使用这二者的话需要考虑语言差异的问题。
同时,在选择的时候也需要考虑产品费用,目前notion、石墨文档、Cofluence对于一定人数规模的团队是会收费的。而钉钉和飞书的使用成本更低一些。
我们都知道,让员工在工作之余进行文档总结,创造整理是一件非常反人性的事情,是对抗熵增这一自然规律的事情。那么打破熵增的办法是什么?那就是打破封闭空间。引入外部激励。
我们可以建立一套机制,鼓励团队成员维护知识库。比如建立一套积分机制,新建一篇文章获取一定积分,为其他人文章评论、点赞、举报获取一定积分,文章阅读量、点赞量达到一定数值获取一定积分。最后用积分作为考核标准,获得额外的奖励。这个奖励最好不要和工资挂钩,很容易被喷卷。
这里只是一个建议,所有的机制都应该是为了让团队成员注重知识管理,培养知识管理的习惯。
团队管理在团队初期是一件附加值很低的事情,很多团队选择不关心。这就很像团队文化一样,一家企业在创业初期都是野蛮生长,基本没人会关心企业文化,也不会关心团队知识沉淀。而当公司快速发展具备一定规模时,还能凝聚大家在一起往前走的,一定是企业文化。
我们会说阿里人、华为人、腾讯人,这个标签贴完,你会自然对这个群体有一种固化的认知,这就是梁宁说的集体人格,背后本质是企业文化的引导。同样,团队发展到一定规模,没有谁会继续无视团队知识管理。
而无论协同办公产品钉钉、飞书,还是面向未来的工具Notion,亦或是专业的知识库Confluence。在知识管理上只能做到“术”的帮助,而真正管理好知识更需要“道”和“法”的引导和规范。
希望这边文章对你有帮助,下一次我们再聊一下个人知识管理,也聊一聊知识管理的“道”和“法”。
忙里偷贤,公众号:忙里偷贤,人人都是产品经理专栏作家。B端产品,低代码玩家,工具类产品思考者。热爱分享,务实的理想主义者。
本文原创发布于人人都是产品经理,未经许可,禁止转载。
题图来自 Pexels,基于CC0协议
ython 风格规范(Google)
本项目并非 Google 官方项目, 而是由国内程序员凭热情创建和维护。
如果你关注的是 Google 官方英文版, 请移步 Google Style Guide
以下代码中 Yes 表示推荐,No 表示不推荐。
分号
不要在行尾加分号, 也不要用分号将两条命令放在同一行。
行长度
每行不超过80个字符
以下情况除外:
不要使用反斜杠连接行。
Python会将 圆括号, 中括号和花括号中的行隐式的连接起来 , 你可以利用这个特点. 如果需要, 你可以在表达式外围增加一对额外的圆括号。
推荐: foo_bar(self, width, height, color='black', design=None, x='foo', emphasis=None, highlight=0) if (width==0 and height==0 and color=='red' and emphasis=='strong'):
如果一个文本字符串在一行放不下, 可以使用圆括号来实现隐式行连接:
x=('这是一个非常长非常长非常长非常长 ' '非常长非常长非常长非常长非常长非常长的字符串')
在注释中,如果必要,将长的URL放在一行上。
Yes: # See details at # http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html No: # See details at # http://www.example.com/us/developer/documentation/api/content/\ # v2.0/csv_file_name_extension_full_specification.html
注意上面例子中的元素缩进; 你可以在本文的 :ref:`缩进 <indentation>`部分找到解释.
括号
宁缺毋滥的使用括号
除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的.
Yes: if foo: bar() while x: x=bar() if x and y: bar() if not x: bar() return foo for (x, y) in dict.items(): ... No: if (x): bar() if not(x): bar() return (foo)
缩进
用4个空格来缩进代码
绝对不要用tab, 也不要tab和空格混用. 对于行连接的情况, 你应该要么垂直对齐换行的元素(见 :ref:`行长度 <line_length>` 部分的示例), 或者使用4空格的悬挂式缩进(这时第一行不应该有参数):
Yes: # 与起始变量对齐 foo=long_function_name(var_one, var_two, var_three, var_four) # 字典中与起始值对齐 foo={ long_dictionary_key: value1 + value2, ... } # 4 个空格缩进,第一行不需要 foo=long_function_name( var_one, var_two, var_three, var_four) # 字典中 4 个空格缩进 foo={ long_dictionary_key: long_dictionary_value, ... } No: # 第一行有空格是禁止的 foo=long_function_name(var_one, var_two, var_three, var_four) # 2 个空格是禁止的 foo=long_function_name( var_one, var_two, var_three, var_four) # 字典中没有处理缩进 foo={ long_dictionary_key: long_dictionary_value, ... }
空行
顶级定义之间空两行, 方法定义之间空一行
顶级定义之间空两行, 比如函数或者类定义. 方法定义, 类定义与第一个方法之间, 都应该空一行. 函数或方法中, 某些地方要是你觉得合适, 就空一行.
空格
按照标准的排版规范来使用标点两边的空格
括号内不要有空格.
按照标准的排版规范来使用标点两边的空格
Yes: spam(ham[1], {eggs: 2}, []) No: spam( ham[ 1 ], { eggs: 2 }, [ ] )
不要在逗号, 分号, 冒号前面加空格, 但应该在它们后面加(除了在行尾).
Yes: if x==4: print x, y x, y=y, x No: if x==4 : print x , y x , y=y , x
参数列表, 索引或切片的左括号前不应加空格.
Yes: spam(1) no: spam (1) Yes: dict['key']=list[index] No: dict ['key']=list [index]
在二元操作符两边都加上一个空格, 比如赋值(=), 比较(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布尔(and, or, not). 至于算术操作符两边的空格该如何使用, 需要你自己好好判断. 不过两侧务必要保持一致.
Yes: x==1 No: x<1
当'='用于指示关键字参数或默认参数值时, 不要在其两侧使用空格.
Yes: def complex(real, imag=0.0): return magic(r=real, i=imag) No: def complex(real, imag=0.0): return magic(r=real, i=imag)
不要用空格来垂直对齐多行间的标记, 因为这会成为维护的负担(适用于:, #,=等):
Yes: foo=1000 # 注释 long_name=2 # 注释不需要对齐 dictionary={ "foo": 1, "long_name": 2, } No: foo=1000 # 注释 long_name=2 # 注释不需要对齐 dictionary={ "foo" : 1, "long_name": 2, }
Shebang
大部分.py文件不必以#!作为文件的开始. 根据 PEP-394 , 程序的main文件应该以 #!/usr/bin/python2或者 #!/usr/bin/python3开始.
(译者注: 在计算机科学中, Shebang (也称为Hashbang)是一个由井号和叹号构成的字符串行(#!), 其出现在文本文件的第一行的前两个字符. 在文件中存在Shebang的情况下, 类Unix操作系统的程序载入器会分析Shebang后的内容, 将这些内容作为解释器指令, 并调用该指令, 并将载有Shebang的文件路径作为该解释器的参数. 例如, 以指令#!/bin/sh开头的文件在执行时会实际调用/bin/sh程序.)
#!先用于帮助内核找到Python解释器, 但是在导入模块时, 将会被忽略. 因此只有被直接执行的文件中才有必要加入#!.
注释
确保对模块, 函数, 方法和行内注释使用正确的风格
文档字符串
Python有一种独一无二的的注释方式: 使用文档字符串. 文档字符串是包, 模块, 类或函数里的第一个语句. 这些字符串可以通过对象的__doc__成员被自动提取, 并且被pydoc所用. (你可以在你的模块上运行pydoc试一把, 看看它长什么样). 我们对文档字符串的惯例是使用三重双引号"""( PEP-257 ). 一个文档字符串应该这样组织: 首先是一行以句号, 问号或惊叹号结尾的概述(或者该文档字符串单纯只有一行). 接着是一个空行. 接着是文档字符串剩下的部分, 它应该与文档字符串的第一行的第一个引号对齐. 下面有更多文档字符串的格式化规范.
模块
每个文件应该包含一个许可样板. 根据项目使用的许可(例如, Apache 2.0, BSD, LGPL, GPL), 选择合适的样板.
函数和方法
下文所指的函数,包括函数, 方法, 以及生成器.
一个函数必须要有文档字符串, 除非它满足以下条件:
文档字符串应该包含函数做什么, 以及输入和输出的详细描述. 通常, 不应该描述"怎么做", 除非是一些复杂的算法. 文档字符串应该提供足够的信息, 当别人编写代码调用该函数时, 他不需要看一行代码, 只要看文档字符串就可以了. 对于复杂的代码, 在代码旁边加注释会比使用文档字符串更有意义.
关于函数的几个方面应该在特定的小节中进行描述记录, 这几个方面如下文所述. 每节应该以一个标题行开始. 标题行以冒号结尾. 除标题行外, 节的其他内容应被缩进2个空格.
Args:
列出每个参数的名字, 并在名字后使用一个冒号和一个空格, 分隔对该参数的描述.如果描述太长超过了单行80字符,使用2或者4个空格的悬挂缩进(与文件其他部分保持一致). 描述应该包括所需的类型和含义. 如果一个函数接受*foo(可变长度参数列表)或者**bar (任意关键字参数), 应该详细列出*foo和**bar.
Returns: (或者 Yields: 用于生成器)
描述返回值的类型和语义. 如果函数返回None, 这一部分可以省略.
Raises:
列出与接口有关的所有异常.
def fetch_bigtable_rows(big_table, keys, other_silly_variable=None): """Fetches rows from a Bigtable. Retrieves rows pertaining to the given keys from the Table instance represented by big_table. Silly things may happen if other_silly_variable is not None. Args: big_table: An open Bigtable Table instance. keys: A sequence of strings representing the key of each table row to fetch. other_silly_variable: Another optional variable, that has a much longer name than the other args, and which does nothing. Returns: A dict mapping keys to the corresponding table row data fetched. Each row is represented as a tuple of strings. For example: {'Serak': ('Rigel VII', 'Preparer'), 'Zim': ('Irk', 'Invader'), 'Lrrr': ('Omicron Persei 8', 'Emperor')} If a key from the keys argument is missing from the dictionary, then that row was not found in the table. Raises: IOError: An error occurred accessing the bigtable.Table object. """ pass
类
类应该在其定义下有一个用于描述该类的文档字符串. 如果你的类有公共属性(Attributes), 那么文档中应该有一个属性(Attributes)段. 并且应该遵守和函数参数相同的格式.
class SampleClass(object): """Summary of class here. Longer class information.... Longer class information.... Attributes: likes_spam: A boolean indicating if we like SPAM or not. eggs: An integer count of the eggs we have laid. """ def __init__(self, likes_spam=False): """Inits SampleClass with blah.""" self.likes_spam=likes_spam self.eggs=0 def public_method(self): """Performs operation blah."""
块注释和行注释
最需要写注释的是代码中那些技巧性的部分. 如果你在下次 代码审查 的时候必须解释一下, 那么你应该现在就给它写注释. 对于复杂的操作, 应该在其操作开始前写上若干行注释. 对于不是一目了然的代码, 应在其行尾添加注释.
# We use a weighted dictionary search to find out where i is in # the array. We extrapolate position based on the largest num # in the array and the array size and then do binary search to # get the exact number. if i & (i-1)==0: # true iff i is a power of 2
为了提高可读性, 注释应该至少离开代码2个空格.
另一方面, 绝不要描述代码. 假设阅读代码的人比你更懂Python, 他只是不知道你的代码要做什么.
# BAD COMMENT: Now go through the b array and make sure whenever i occurs # the next element is i+1
类
如果一个类不继承自其它类, 就显式的从object继承. 嵌套类也一样.
Yes: class SampleClass(object): pass class OuterClass(object): class InnerClass(object): pass class ChildClass(ParentClass): """Explicitly inherits from another class already.""" No: class SampleClass: pass class OuterClass: class InnerClass: pass
继承自 object 是为了使属性(properties)正常工作, 并且这样可以保护你的代码, 使其不受Python 3000的一个特殊的潜在不兼容性影响. 这样做也定义了一些特殊的方法, 这些方法实现了对象的默认语义, 包括 __new__, __init__, __delattr__, __getattribute__, __setattr__, __hash__, __repr__, and __str__ .
字符串
Yes: x=a + b x='%s, %s!' % (imperative, expletive) x='{}, {}!'.format(imperative, expletive) x='name: %s; score: %d' % (name, n) x='name: {}; score: {}'.format(name, n) No: x='%s%s' % (a, b) # use + in this case x='{}{}'.format(a, b) # use + in this case x=imperative + ', ' + expletive + '!' x='name: ' + name + '; score: ' + str(n)
避免在循环中用+和+=操作符来累加字符串. 由于字符串是不可变的, 这样做会创建不必要的临时对象, 并且导致二次方而不是线性的运行时间. 作为替代方案, 你可以将每个子串加入列表, 然后在循环结束后用 .join 连接列表. (也可以将每个子串写入一个 cStringIO.StringIO 缓存中.)
Yes: items=['<table>'] for last_name, first_name in employee_list: items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name)) items.append('</table>') employee_table=''.join(items) No: employee_table='<table>' for last_name, first_name in employee_list: employee_table +='<tr><td>%s, %s</td></tr>' % (last_name, first_name) employee_table +='</table>'
在同一个文件中, 保持使用字符串引号的一致性. 使用单引号'或者双引号"之一用以引用字符串, 并在同一文件中沿用. 在字符串内可以使用另外一种引号, 以避免在字符串中使用. PyLint已经加入了这一检查.
Yes: Python('Why are you hiding your eyes?') Gollum("I'm scared of lint errors.") Narrator('"Good!" thought a happy Python reviewer.') No: Python("Why are you hiding your eyes?") Gollum('The lint. It burns. It burns us.') Gollum("Always the great lint. Watching. Watching.")
为多行字符串使用三重双引号"""而非三重单引号'''. 当且仅当项目中使用单引号'来引用字符串时, 才可能会使用三重'''为非文档字符串的多行字符串来标识引用. 文档字符串必须使用三重双引号""". 不过要注意, 通常用隐式行连接更清晰, 因为多行字符串与程序其他部分的缩进方式不一致.
Yes: print ("This is much nicer.\n" "Do it this way.\n") No: print """This is pretty ugly. Don't do this. """
文件和sockets
在文件和sockets结束时, 显式的关闭它.
除文件外, sockets或其他类似文件的对象在没有必要的情况下打开, 会有许多副作用, 例如:
而且, 幻想当文件对象析构时, 文件和sockets会自动关闭, 试图将文件对象的生命周期和文件的状态绑定在一起的想法, 都是不现实的. 因为有如下原因:
推荐使用 "with"语句 以管理文件:
with open("hello.txt") as hello_file: for line in hello_file: print line
对于不支持使用"with"语句的类似文件的对象,使用 contextlib.closing():
import contextlib with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page: for line in front_page: print line
Legacy AppEngine 中Python 2.5的代码如使用"with"语句, 需要添加 "from __future__ import with_statement".
TODO注释
为临时代码使用TODO注释, 它是一种短期解决方案. 不算完美, 但够好了.
TODO注释应该在所有开头处包含"TODO"字符串, 紧跟着是用括号括起来的你的名字, email地址或其它标识符. 然后是一个可选的冒号. 接着必须有一行注释, 解释要做什么. 主要目的是为了有一个统一的TODO格式, 这样添加注释的人就可以搜索到(并可以按需提供更多细节). 写了TODO注释并不保证写的人会亲自解决问题. 当你写了一个TODO, 请注上你的名字.
# TODO(kl@gmail.com): Use a "*" here for string repetition. # TODO(Zeke) Change this to use relations.
如果你的TODO是"将来做某事"的形式, 那么请确保你包含了一个指定的日期("2009年11月解决")或者一个特定的事件("等到所有的客户都可以处理XML请求就移除这些代码").
导入格式
每个导入应该独占一行
Yes: import os import sys No: import os, sys
导入总应该放在文件顶部, 位于模块注释和文档字符串之后, 模块全局变量和常量之前. 导入应该按照从最通用到最不通用的顺序分组:
每种分组中, 应该根据每个模块的完整包路径按字典序排序, 忽略大小写.
import foo from foo import bar from foo.bar import baz from foo.bar import Quux from Foob import ar
语句
通常每个语句应该独占一行
不过, 如果测试结果与测试语句在一行放得下, 你也可以将它们放在同一行. 如果是if语句, 只有在没有else时才能这样做. 特别地, 绝不要对 try/except 这样做, 因为try和except不能放在同一行.
Yes: if foo: bar(foo) No: if foo: bar(foo) else: baz(foo) try: bar(foo) except ValueError: baz(foo) try: bar(foo) except ValueError: baz(foo)
访问控制
在Python中, 对于琐碎又不太重要的访问函数, 你应该直接使用公有变量来取代它们, 这样可以避免额外的函数调用开销. 当添加更多功能时, 你可以用属性(property)来保持语法的一致性.
(译者注: 重视封装的面向对象程序员看到这个可能会很反感, 因为他们一直被教育: 所有成员变量都必须是私有的! 其实, 那真的是有点麻烦啊. 试着去接受Pythonic哲学吧)
另一方面, 如果访问更复杂, 或者变量的访问开销很显著, 那么你应该使用像 get_foo() 和 set_foo() 这样的函数调用. 如果之前的代码行为允许通过属性(property)访问 , 那么就不要将新的访问函数与属性绑定. 这样, 任何试图通过老方法访问变量的代码就没法运行, 使用者也就会意识到复杂性发生了变化.
命名
module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_VAR_NAME, instance_var_name, function_parameter_name, local_var_name.
应该避免的名称
命名约定
Python之父Guido推荐的规范
TypePublicInternalModuleslower_with_under_lower_with_underPackageslower_with_under ClassesCapWords_CapWordsExceptionsCapWords Functionslower_with_under()_lower_with_under()Global/Class ConstantsCAPS_WITH_UNDER_CAPS_WITH_UNDERGlobal/Class Variableslower_with_under_lower_with_underInstance Variableslower_with_under_lower_with_under (protected) or __lower_with_under (private)Method Nameslower_with_under()_lower_with_under() (protected) or __lower_with_under() (private)Function/Method Parameterslower_with_under Local Variableslower_with_under
Main
即使是一个打算被用作脚本的文件, 也应该是可导入的. 并且简单的导入不应该导致这个脚本的主功能(main functionality)被执行, 这是一种副作用. 主功能应该放在一个main()函数中.
在Python中, pydoc以及单元测试要求模块必须是可导入的. 你的代码应该在执行主程序前总是检查 if __name__=='__main__' , 这样当模块被导入时主程序就不会被执行.
def main(): ... if __name__=='__main__': main()
所有的顶级代码在模块导入时都会被执行. 要小心不要去调用函数, 创建对象, 或者执行那些不应该在使用pydoc时执行的操作.
*请认真填写需求信息,我们会在24小时内与您取得联系。