Python 和 Lua 学习比较 (转)

[复制链接]
2627|6
 楼主| gaoyang9992006 发表于 2018-9-9 23:13 | 显示全部楼层 |阅读模式

好记性不如烂笔头。
作的笔记以后也能来再看看。

python有多种语言写成的版本,这里只记录C/C++写的版本,lua本身是使用标准C/C++编写的。

所以各位同学知道C的强大了吧,我觉得作为程序员,应该都要学一下C/C++,这是你以后成长的奠基石。以后你如果不爽python或者lua了,自己编一种新的脚本语言,^_^

python和lua都是解释类语言,不用编译和链接,支持动态类型语言,意思就是这两个家伙都支持变量的类型变化,比如:

python:

  1. >>> type(a)
  2. ''' 输出
  3. #Traceback (most recent call last):
  4. #  File "<stdin>", line 1, in <module>
  5. #NameError: name 'a' is not defined
  6. '''
  7. >>> a = "123"
  8. >>> type(a) # 输出 <class 'str'>
  9. >>> id(a) # 输出 35672112 - 每个人的结果不一样
  10. >>> a = 12
  11. >>> type(a) # 输出 <class 'int'>
  12. >>> id(a) # 输出 1488898480 - 每个人的结果不一样
  13. >>> a = 12.3
  14. >>> type(a) # 输出 <class 'float'>
  15. >>> id(a) # 输出 5734688 - 每个人的结果不一样
  16. >>> 0/0 '''作死除法
  17. Traceback (most recent call last):
  18.   File "<stdin>", line 1, in <module>
  19. ZeroDivisionError: division by zero
  20. '''

lua:

  1. --[[
  2.     lua多行注释
  3. --]] --这里习惯在前面加上'--'
  4. > type(a) -- 输出 nil
  5. > a = "123"
  6. > type(a) -- 输出 string
  7. > a = 12
  8. > type(a) -- 输出 number
  9. > a = 12.3
  10. > type(a) -- 输出 number
  11. > 0/0 -- 输出 nan  意思就是Not a Number 不是数字
  12. > type(0/0) -- 输出 number
  13. --[[
  14.     上面是否让你意外呢? 虽然是nan 但是它的类型还是number的
  15. --]]

上面的代码演示了最基本的类型,在python中,使用未定义的变量会报错,而在lua中,只是简单的nil类型数据,相对于python,lua没有id函数,把所有的整数,浮点数都统称为number类型。细看python,我们发现虽然我们的变量a没有变,但是通过id函数,我们看出来了,a其实还是变了,这个具体的变法,我们不需要关心,我们只需要了解有这么回事,C/C++程序员知道,这里其实是存放a内容的内存地址变了,是一个新的对象。至于0除以0的问题,大家看注释了解就好了。
lua包含的数据类型有nil 、boolean 、number 、string 、table 、function 、userdata和thread。
Python后面再总结。

python和lua的提示也要了解一下,后面就不提示这个内容了。
python 默认提示 >>> ; 继续行提示 …
lua 默认提示 > ; 继续行提示 >>
前面不带符号的就是计算的输出了。
编码格式的话,我觉得如果没有必要,尽量都用UTF8,以后你会感谢我的^_^。

注释的方法,我已经放在上面的代码注释中了。


 楼主| gaoyang9992006 发表于 2018-9-9 23:14 | 显示全部楼层
在继续学习之前,我总结了个查询lua API的方法
  1. for k,v in pairs(_G) do print(k,v) end #它会告诉我们lua有哪些可用table或者function
至于python,则是通过dir内建函数
  1. import builtins
  2. dir(builtins)#跟lua一样,查看当前内建的变量和函数,模块
  3. dir()#查看当前定义的变量,函数,模块
  4. import sys
  5. dir(sys)#查看该sys包下可用的变量,函数,模块
计算能力的话,两者都一样,都可以当计算器使用
python:
  1. >>> 2 + 2
  2. 4 #前面没有符号,这是python的输出结果
  3. >>> 50 - 5*6
  4. 20
  5. >>> (50 - 5*6) / 4
  6. 5.0
  7. >>> 8 / 5  # 除法总是返回一个浮点数
  8. 1.6
  9. >>> 5 // 3 #取整
  10. 1
  11. >>> 5 % 3 #取余
  12. 2
  13. >>> width = 20
  14. >>> height = 5 * 9
  15. >>> width * height
  16. 900
  17. >>> 3 * 3.75 / 1.5
  18. 7.5 #整数与浮点数的计算,python会把整数转换成浮点数
  19. >>> 7.0 / 2
  20. 3.5
lua返回的结果是跟python一样的,所以代码就不给出了。虽然输出的结果一样,但是我们要知晓,python区分int和float,lua都是number.

 楼主| gaoyang9992006 发表于 2018-9-9 23:16 | 显示全部楼层
下面来看看两者的幂运算符和对待未申明变量的区别
python:
  1. >>> 5**2 #幂运算符 **
  2. 25 # 这里是 int
  3. >>> n  # 试图访问未申明变量
  4. Traceback (most recent call last):
  5.   File "<stdin>", line 1, in <module>
  6. NameError: name 'n' is not defined
lua:

> 5^2 --幂运算符 ^
25.0 -- 这里虽然是number,但是是浮点数,c程序员懂为什么
> n
nil

在交互模式下,python还提供了一个功能就是保留当前的计算结果,lua未提供。
  1. >>> tax = 12.5 / 100
  2. >>> price = 100.50
  3. >>> price * tax
  4. 12.5625
  5. >>> price + _ #这里的 _ 指的就是上次的计算结果12.5625
  6. 113.0625
  7. >>> _ + 1
  8. 114.0625
  • 注:记住 python的_是只读的,切忌对它赋值。如果你这么做了,那就加一句 del _

虽然python还为我们提供了强大的Decimal、Fraction和complex number,这里就不一一介绍了。


 楼主| gaoyang9992006 发表于 2018-9-9 23:19 | 显示全部楼层
在交互模式下两者对字符串的输出稍显差异
python:
  1. >>> 'spam eggs'
  2. 'spam eggs' #这里会有单引号括起来,表示是字符串
  3. >>> print('spam eggs') #打印函数
  4. spam eggs
  5. >>> s = 'First line.\nSecond line.'  # \n代表新行
  6. >>> s  # without print(), \n is included in the output
  7. 'First line.\nSecond line.'
  8. >>> print(s)  # with print(), \n produces a new line
  9. First line.
  10. Second line.
lua:

  1. > 'spam eggs'
  2. spam eggs -- lua的话就是普通的打印
  3. > print('spam eggs') #打印函数
  4. spam eggs
  5. > print('spam eggs')
  6. spam eggs
  7. > s = 'First line.\nSecond line.' -- \n代表新行
  8. > s
  9. First line.
  10. Second line.
对于单引号,双引号的相互嵌套,或者反斜杠\的转义,两者没有任何区别。
python:

  1. >>> print('spam eggs')  # single quotes
  2. spam eggs
  3. >>> print('doesn\'t')  # use \' to escape the single quote...
  4. doesn't
  5. >>> print("doesn't")  # ...or use double quotes instead
  6. doesn't
  7. >>> print('"Yes," he said.')
  8. "Yes," he said.
  9. >>> print(""Yes," he said.")
  10. "Yes," he said.
  11. >>> print('"Isn\'t," she said.')
  12. "Isn\'t," she said.

虽然有那么多写法,但是我觉得,作为一名优秀的程序员,我们还是不要窜来窜去的,对字符使用统一的写法,要么用'',要么用"",否则别人看了你的代码一定会头疼的^_^

有时候我们又不想要转义。
假如有这样一个目录 C:\name我们需要打印出来。

python:

  1. >>> print("C:\name") # 结果,这里的\n被当成是换行符了,lua也是这结果
  2. C:\some
  3. ame

共同的解决方法是 print("C:\\name"),不过python还提供了另一种方法就是print(r"C:\name") 叫 raw strings。
python还对多行字符串提供了更加方便的解决方法"""..."""或者'''...''',自动读取换行符如果不想要换行符可以加转义符\

python:

  1. print("""\
  2. Usage: thingy [OPTIONS]
  3.      -h                        Display this usage message
  4.      -H hostname               Hostname to connect to
  5. """)
  6. Usage: thingy [OPTIONS]
  7.      -h                        Display this usage message
  8.      -H hostname               Hostname to connect to



 楼主| gaoyang9992006 发表于 2018-9-9 23:21 | 显示全部楼层
下面是两者拼接字符串的区别
python:
  1. >>> print("un" + "ium") #能拼接两个常量字符串
  2. unium
  3. >>> a = "un"
  4. >>> print(a + a + "ium") #也能拼接变量(类型需要是str,否则报错)和常量字符串,lua中的加号不能拼接字符串,但有其他功能
  5. ununium
  6. >>> print("un" "ium" "un" "ium")
  7. '''
  8. 自动拼接相邻的字符串,不过这个只能拼接常量字符串,不能拼接变量和常量字符串;但是可以用来对很长的打印信息分行,打印结果也是单行的。lua不行
  9. '''
  10. uniumunium
  11. >>> print(a*3) #这个比较厉害,可以对字符串做乘法,意思就是重复字符串,lua不可以
  12. ununun
lua:

  1. > print("un" .. "ium") -- 类似python的+,但是python不具有这个操作符
  2. > a = "un"
  3. > print(a .. a .. "ium") -- 类似python的+
  4. ununium
  5. > print(10 .. 20) -- 还能连接数字,输出类型是string,注意点点要跟数字10分开,不然会被当成小数的。
  6. 1020
  7. > print(10 ..20) -- 不推荐这样写
  8. 1020
  9. > a = "10"
  10. > print(a + 1) -- 当一个string加number的时候,lua会先判断这个string能否转换成number(tonumber函数),能就得出加出来的数,否则报错
  11. 11.0
  12. > a = "10a"
  13. > print(a+1) -- 这里就报错了
  14. stdin:1: attempt to perform arithmetic on a string value (global 'a')
  15. stack traceback:
  16.         stdin:1: in main chunk
  17.         [C]: in ?
对字符串中某个字符的读取也不一样,python提供的功能更强大,lua只能走string的函数
python:

  1. >>> # 在python中索引起步是0
  2. >>> a = "1234567"
  3. >>> print(a[0])
  4. 1
  5. >>> print(a[-1])
  6. 7
  7. >>> print(a[2:4]) # : 这个符号对应的区间是:[) 前面闭区间,后面开区间
  8. 34
  9. >>> print(a[2:0]) # 等同 print(a[-5:-7])
  10.     #无输出
  11. >>> print(a[-3:-1])
  12. 56
  13. >>> print(a[:2])
  14. 12
  15. >>> print(a[2:])
  16. 34567
  17. >>> a[8] # 越界访问
  18. Traceback (most recent call last):
  19.   File "<stdin>", line 1, in <module>
  20. IndexError: string index out of range
  21. >>> a[-8:] # 越界,输出全部
  22. '1234567'
  23. '''
  24. 对应的字符串索引图表就是
  25. +---+---+---+---+---+---+---+---+---+---+
  26.      |   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
  27. +---+---+---+---+---+---+---+---+---+---+
  28.          0   1   2   3   4   5   6   7   8
  29. -9  -8  -7  -6  -5  -4  -3  -2  -1
  30. '''
  31. >>> a[0] = "a" # 不能赋值
  32. Traceback (most recent call last):
  33.   File "<stdin>", line 1, in <module>
  34. TypeError: 'str' object does not support item assignment
  35. >>> len(a) #查看字符串长度
  36. 7
lua:

  1. > -- 在lua中索引起步是1,嘿嘿,区别于各种语言
  2. > a = "1234567"
  3. > print(string.sub(a,1)) -- 当然你要把这里的1改成0也是可以的,不推荐
  4. 1234567
  5. > print(string.sub(a,2,1)) -- 无输出

  6. > print(string.sub(a,3,3)) -- 等同python的a[2:3],python不许这种写法:a[2:2]。
  7. > -- 所以我们就知道了,对于lua,它的区间是:[] 前后闭区间
  8. 3
  9. > string.sub(a,8) -- 越界了,无输出

  10. > string.sub(a,-8) -- 越界了,输出全部
  11. 1234567
  12. --[[
  13. 对应的字符串索引图表就是,
  14. +---+---+---+---+---+---+---+---+---+---+
  15.      |   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
  16. +---+---+---+---+---+---+---+---+---+---+
  17.      0   1   2   3   4   5   6   7   8   9
  18. -9  -8  -7  -6  -5  -4  -3  -2  -1
  19. --]]
  20. > string.len(a) --查看字符串长度
  21. 7

对于用正向索引还是负向索引看哪个用的方便吧,一般用正向的。
通过上面的比较,python对字符串访问提供的功能更多,lua要更接近C的方式一点(只能通过函数操作)。

python还有list类型,lua可以通过table的方式实现类似的功能,看例子:
python:

  1. >>> lst = [1,4,9,16]
  2. >>> type(lst)
  3. <class 'list'>
  4. >>> lst[0] # []的访问跟上面字符串的访问一样
  5. 1
  6. >>> lst[1]
  7. 4
  8. >>> lst[2]
  9. 9
  10. >>> lst[1:10] # lua不支持
  11. [4, 9, 16]
  12. >>> lst[-1]
  13. 16
  14. >>> id(lst)
  15. 35530696
  16. >>> id(lst[:]) # 每次[]操作,返回都是新的list对象
  17. 35530888
  18. >>> lst2 = [25,36]
  19. >>> lst + lst2 # python还支持两个list的串联
  20. [1, 4, 9, 16, 25, 36]
  21. >>> lst[3] = 81 # list不同于str,可以赋值
  22. >>> lst
  23. [1, 4, 9, 81]
  24. >>> lst.append(100) # 通过append函数追加数据
  25. >>> lst
  26. [1, 4, 9, 81, 100]

  27. >>> # python不仅可以单个赋值还能区间赋值 这个lua没有
  28. >>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
  29. >>> letters
  30. ['a', 'b', 'c', 'd', 'e', 'f', 'g']
  31. >>> # 替换成大写
  32. >>> letters[2:5] = ['C', 'D', 'E']
  33. >>> letters
  34. ['a', 'b', 'C', 'D', 'E', 'f', 'g']
  35. >>> # 删除它们
  36. >>> letters[2:5] = []
  37. >>> letters
  38. ['a', 'b', 'f', 'g']
  39. >>> # 用一个空的来清空这个list
  40. >>> letters[:] = []
  41. >>> letters
  42. []
  43. >>> len(letters) # 使用函数 len 查看容量
  44. 0

  45. >>> letters = [1,2,3,"a","b"] # 虽然python支持,但是我们最好不要这样做,数据类型最好要保持一致
  46. >>> letters
  47. [1, 2, 3, 'a', 'b']

  48. >>> a = ['a', 'b', 'c'] # python还支持list嵌套
  49. >>> n = [1, 2, 3]
  50. >>> x = [a, n]
  51. >>> x
  52. [['a', 'b', 'c'], [1, 2, 3]]
  53. >>> x[0]
  54. ['a', 'b', 'c']
  55. >>> x[0][1]
  56. 'b'

lua:

  1. > lst = {1,4,9,16}
  2. > lst
  3. table: 00448638
  4. > lst[1] -- lua从索引1开始
  5. 1
  6. > lst[2]
  7. 4
  8. > lst[3]
  9. 9
  10. > lst[-1] -- lua的table []操作不支持负数访问
  11. nil
  12. > lst1 = {25,36}
  13. > lst + lst2 -- lua 不支持 table相加,如果要实现这个功能需要借助table的函数,后面再说~
  14. stdin:1: attempt to perform arithmetic on a table value (global 'lst')
  15. stack traceback:
  16.         stdin:1: in main chunk
  17.         [C]: in ?
  18. > lst[4] = 81 -- lua也可以赋值
  19. > lst[4]
  20. 81
  21. > #lst -- 通过 # 来取得 table 的容量
  22. 4

  23. > letters = {1,2,3,"a","b"} -- 虽然lua可以这样做,但是我们尽量保证我们的table数据类型一致
  24. > letters[1]
  25. 1
  26. > letters[4]
  27. a

  28. > a = {"a","b","c"} —— lua也支持table嵌套
  29. > n = {1,2,3}
  30. > x = {a,n}
  31. > x[1][1]
  32. a
  33. > x[2][1]
  34. 1



 楼主| gaoyang9992006 发表于 2018-9-9 23:22 | 显示全部楼层
最后我们再来看一下两者的打印函数 print
python:
  1. >>> help(print) # 使用help函数,我们可以看到它的文档解释
  2. Help on built-in function print in module builtins:

  3. print(...)
  4.     print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

  5.     Prints the values to a stream, or to sys.stdout by default.
  6.     Optional keyword arguments:
  7.     file:  a file-like object (stream); defaults to the current sys.stdout.
  8.     sep:   string inserted between values, default a space.
  9.     end:   string appended after the last value, default a newline.
  10.     flush: whether to forcibly flush the stream.

  11. >>>#sep 参数表示间隔字符串输出
  12. >>>#end 参数表示打印结束后的字符串输出
  13. >>>#如果参数不明白,下面的例子看了就懂了
  14. >>> print(1,2,3,4,5)
  15. 1 2 3 4 5
  16. >>> print(1,2,3,4,5,sep=",",end=".")
  17. 1,2,3,4,5.>>>#这里由于把end的参数改成.所以没有回车

lua:
  1. >-- lua 查文档 就一个 print (···),它建议我们用string.format来定制自己的打印格式,这个函数后面再细说。

  2. > print(1,2,3,4,5) -- lua 默认分的很开
  3. 1       2       3       4       5
 楼主| gaoyang9992006 发表于 2018-9-9 23:22 | 显示全部楼层
未完待续。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16403

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部