前几天同学过来,于是请了几天假,加上紧接着的元旦假期,工作时间比较闲暇,因此有时间上网看看资料,学学Python。尽管Python相对简单,但是对于我这种一直使用C#的程序员来说,使用起来并不是很舒服,具体体现在下面几点:
- 相比C#和Java,Python规范性上欠佳,比如其特殊的双下划线方法,用起来非常不自在,需要一段时间适应;
- Python中有非常优秀的列表推导及生成器等语法,之前没有这么用过,所以不习惯,然而我非常喜欢这样的写法;
- 没有了强大的Visual Studio支撑,编码效率比不上C#,但是Python作为脚本语言完成任务所需的代码量却要比C#、Java这种大型语言少很多,因为一般的小型任务一般不需要考虑写一堆类出来,这一点也是其优势。但是得益于VS Code强大的扩展,使用VS Code编写Python代码也能达到VS的80%的水平。
啃了两天《流畅的Python》之后发现这本书还是偏向高级内容,所以我又找了本《Python基础教程》看。概览后发现,不管是《流畅的Python》还是《Python基础教程》,在很多地方都体现出了Python的理念——将代码语言化,这也是很多其他高级语言追求的目标,但Python在这方面做的更好,特别是其列表推导式:
1 | numbers_less_than_10 = [num for num in range(10)] |
上面这行代码浅显易懂,可以理解为:对于0~9中的每一个数,将其加入到一个列表中,完全比其他语言的for循环在语义上要明确很多,比如C#写出来语义就没这么接近人类的自然语言:
1 | List<int> numbersLessThan10 = new List<int>(); |
虽然你也可以不这么麻烦的写成类似下面这样(需要using System.Linq):
1 | List<int> numbersLessThan10 = Enumerable.Range(0, 10).ToList(); |
但是这里的List<int>
还是没有Python中的方括号简单直接。既然了解到了将代码写的更加自然语言化所带来的优势,那么平时的代码编写就需要仔细思考、多多总结。
恰好昨天看到一个比较简单的编程题目(一道华为的社招机试题),我这里就尽可能用比较能接近人类自然语言的方式将其代码化:
1 | 骰子有6个面,现在用1,2,3,4,5,6分别代表一个骰子的左,右,前,后,上,下的初始位置。 |
现用C#语言实现如下:
1 | public class DiceSurfaceStatus |
这里我为了代码阅读起来更像书籍,做了一些额外的工作:
使用枚举表示骰子的六个面,使枚举的值正好对应到保存骰子状态的数组surfaceStatus的下标,这样后续的交换操作只需要传入当前要交换的面的枚举值即可完成;
将switch块中的内容概括为独立的方法,增强可读性。比如向左翻转(TurnLeft)、向右翻转(TurnRight)、向前翻转(TurnFront)、向后翻转(TurnBack)以及顺时针旋转(RotateRight)和逆时针旋转(RotateLeft);
各个方法的名称需要尽量能概括出所对应的操作。比如2中列举的几个方法,另外还有翻转一次(Rotate)和按照一定的顺序翻转到一个新状态(RotateTo)等方法;
尽可能自然语言化代码。比如交换数组中两个元素的方法(SwapArrayTwoElements),虽然名称已经足够清楚并易于使用,但是将其扩展成新方法(SwapSurface)之后会使其意图更加清楚,调用前者需要使用数字下标(
SwapArrayTwoElements(array,0,1)
),但是使用后者一看就知道是在做什么(SwapSurface(Surface.Front,Surface.Left)
,将前面的面和左边的面交换位置)。
目前为止,虽然我对自己这样的实现方法比较满意,但是这种语言化代码的思想需要今后的经验积累,这也是我的一项长期目标——没有标准答案,尽力而为。