我是先接触 Python3 的,如果我自己主动来选择,可能不会再去学 Ruby(可能先入为主的思想太根深蒂固了,不过最主要的还是太懒了),然鹅由于种种原因,我还是要来看一下Ruby(真是天理难容,/大哭/大哭/大哭),虽然大家都说 Ruby 和 Python 的语法差不多(好像确实如此——不过既然如此,为何要弄两个来折磨大家呢?),所以学习的时候我准备把这两种语言的语法对比一下(给自己找点看下去的动力),毕竟语言不过是解决问题的工具,没什么好坏之分(强行安慰一下自己)。至于开发工具嘛!JetBrains 的全家桶真香,Ruby 和 Python 分别用 RubyMine 和 PyCharm 就好。

Ruby on rails 是 Ruby 的 Web 应用程序框架,据说很牛掰,不过咱也不知道咱也不敢问,等我后面接触到了再说,目前的话,就先当个 surprise 期待着吧!好东西自然分享给大家了,下面的参考资料很不错的哟,也是本文的主要参考资料:

learn x in y minutes where x= Ruby :Learn ruby in Y Minutes

learn x in y minutes where x= Python :Learn Python in Y Minutes

Ruby 代码风格指南:Ruby Coding Style Guides · Ruby China

Ruby 源码安装

解压一个安装包,进入解压文件夹。

[root@master packages]# ll | grep ruby-2.7.1
drwxr-xr-x. 28 root    root         8192 Aug 23 14:52 ruby-2.7.1
-rw-r--r--.  1 root    root     16816471 Mar 31 21:12 ruby-2.7.1.tar.gz
[root@master packages]# cd ruby-2.7.1
[root@master ruby-2.7.1]# pwd
/root/packages/ruby-2.7.1

编译安装 :

[root@master ~]# ./configure --prefix=/usr/local/ruby-2.7.1
[root@master ~]# make && make install

添加以下软连接,否则可能提示找不到:

[root@master packages]# ln -fs /usr/local/ruby-2.7.1/bin/ruby /usr/bin/ruby
[root@master packages]# ln -fs /usr/local/ruby-2.7.1/bin/gem /usr/bin/gem
[root@master packages]# ln -fs /usr/local/ruby-2.7.1/bin/bundle /usr/bin/bundle# ln -fs /usr/local/ruby-2.7.1/bin/irb /usr/local/bin/irb
# ln -fs /usr/local/ruby-2.7.1/bin/pry /usr/local/bin/pry

安装完成:

[root@master ~]# ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
[root@master ~]# gem -v
3.1.2
[root@master ~]# bundle -v
Bundler version 2.1.4

我是在 centOS 虚拟机安装的解释器,可以使用 yum install ruby 命令安装,但是安装的可能不是最新的:

Ruby 依赖包安装

依赖包的话就使用 gem install 命令进行安装,有时候由于网络和墙的原因会一直卡住不动,不过也可以手动下载依赖包进行安装,比如说我安装 pry 的时候就碰到了这种情况,最后手动下载 .gem 文件安装成功(记得添加 --local 参数哟,表示你想使用本地文件进行安装,不然 gem 又会从源地址去下载去了):

[root@master packages]# gem install --local pry-0.13.1.gem
Successfully installed method_source-1.0.0
Successfully installed coderay-1.1.3
Successfully installed pry-0.13.1
Parsing documentation for method_source-1.0.0
Installing ri documentation for method_source-1.0.0
invalid options: -SNw2
(invalid options are ignored)
Parsing documentation for coderay-1.1.3
Installing ri documentation for coderay-1.1.3
Parsing documentation for pry-0.13.1
Installing ri documentation for pry-0.13.1
Done installing documentation for method_source, coderay, pry after 3 seconds
3 gems installed

安装后版本如下:

[root@master ~]# ruby --version
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
[root@master ~]# python3 --version
Python 3.6.8[root@master ~]# gem --version
2.0.14.1
[root@master ~]# pip3 --version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)# 可以先用 wget 命令下载依赖文件
[root@master ~]# ll
-rw-r--r--.  1 root root     92672 May 30 15:24 coderay-1.1.3.gem
-rw-r--r--.  1 root root     13824 Mar 19 21:11 method_source-1.0.0.gem
-rw-r--r--.  1 root root    155136 Apr 12 15:35 pry-0.13.1.gem[root@master ~]# gem install --local coderay-1.1.3.gem
[root@master ~]# gem install --local method_source-1.0.0.gem
[root@master ~]# gem install --local pry-0.13.1.gem
[root@master ~]# pry --version
Pry version 0.13.1 on Ruby 2.0.0
[1] pry(main)> puts "Hello World"
Hello World
=> nil
[2] pry(main)>

Hello World

pry(或者自带的 irb,pry 会更好用一些)可以打开 Ruby 控制台,就像在命令行输入 python3 会进入 Python 命令行一样。话不多说,先来个 Hello world 看看!哇,这俩货的 Hello world 用法都是一样的,你敢信?除了 Ruby 的输出多一个 => nil 之外,好像确实没什么区别,这儿的 nil 你可以把它当成 Python3 里边的 None,也就是箭头 => 右边的 nil 是它的返回值。毕竟这儿只是输出个字符串,自然没什么好返回的。还有一点,Ruby 使用 true 和 false 表示真和假,Python3 使用 True 和 False表示真和假,看起来 Ruby 确实更简化些,至少敲字符的时候省去了摁住 Shift 键的烦恼。

# Ruby
[root@master ~]# pry
[1] pry(main)> print "Hello World"
Hello World=> nil
[2] pry(main)> 
# Python3
[root@master ~]# python3
Python 3.6.8 (default, Aug  7 2019, 17:28:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello World")
Hello World

先不要慌,咱们继续往下看,Ruby 的输出有 print ,puts,p,可见花样是玩出了新高度的,四则运算这块好像区别也不大,只不过涉及到除法的时候,Python3 输出的结果是 Float 型的,如果是 Python2,就和这儿的 Ruby 是一样的了:

# Ruby
irb(main):001:0> puts "Hello World"
Hello World
=> nil
# 注意输出的字符串和返回的 nil 没在同一行,相当于输出后换行了irb(main):002:0> p "Hello World"
"Hello World"
=> "Hello World"
# 注意字符串给自动添加上了双引号,告诉你输出的是个 “字符串”,而且返回值不是 nil 了

Here Document

# test.rbputs <<~EOFthis is the first linethis is the second line
EOF[root@master ruby_learning]# ruby test.rb
this is the first line
this is the second line------------------------------------------------------
# test.rbputs <<-EOFthis is the first linethis is the second line
EOF[root@master ruby_learning]# ruby test.rbthis is the first linethis is the second line

Proc (lambda)

Proc 和 lambda 的区别

# lambda 函数参数检查更为严格
[1] pry(main)> prc1 = Proc.new do |a, b, c|
[1] pry(main)*   puts [a, b, c].inspect
[1] pry(main)* end
=> #<Proc:0x00005619cb3e8d80 (pry):1>
[2] pry(main)> prc1.call(1, 2)
[1, 2, nil]
=> nil
[3] pry(main)> prc2 = lambda do |a, b, c|
[3] pry(main)*   puts [a, b, c].inspect
[3] pry(main)* end
=> #<Proc:0x00005619cb15bbd0 (pry):5 (lambda)>
[4] pry(main)> prc2.call(1, 2)
ArgumentError: wrong number of arguments (given 2, expected 3)
from (pry):5:in "block in __pry__"------------------------------------------------------------
# lambda 可以用 return 返回值
[5] pry(main)> def power_of(n)
[5] pry(main)*   lambda do |x|
[5] pry(main)*     return x ** n
[5] pry(main)*   end
[5] pry(main)* end
=> :power_of
[6] pry(main)> cube = power_of(3)
=> #<Proc:0x00005619cb3e9528 (pry):10 (lambda)>
[7] pry(main)> cube.call(5)
=> 125
[8] pry(main)> def power_of(n)
[8] pry(main)*   Proc.new do |x|
[8] pry(main)*     return x ** n
[8] pry(main)*   end
[8] pry(main)* end
=> :power_of
[9] pry(main)> cube = power_of(3)
=> #<Proc:0x00005619cb4baa60 (pry):17>
[10] pry(main)> cube.call(5)
LocalJumpError: unexpected return
from (pry):18:in `block in power_of'

Proc 自定义带块函数

[11] pry(main)> def total(from, to, &block)
[11] pry(main)*   result = 0
[11] pry(main)*   from.upto(to) do |num|
[11] pry(main)*     if block
[11] pry(main)*       result += block.call(num)
[11] pry(main)*     else
[11] pry(main)*       result += num
[11] pry(main)*     end
[11] pry(main)*   end
[11] pry(main)*   return result
[11] pry(main)* end
=> :total
[12] pry(main)> total(1, 10)
=> 55
[13] pry(main)> total(1, 10) { |num| num ** 2 }
=> 385

%Q, %q, %W, %w, %x, %r, %s, %i

边界符号可以用如下其他符号替换

|...|, #...#, !...!, +...+, (...), [...], <...>, /.../
# Ruby
[8] pry(main)> name = "Ruby"
=> "Ruby"[9] pry(main)> %Q{hello, my name is #{name}}
=> "hello, my name is Ruby"[10] pry(main)> %q{hello, my name is #{name}}
=> "hello, my name is \#{name}"[15] pry(main)> %W{hello world #{name}}
=> ["hello", "world", "Ruby"][16] pry(main)> %w{hello world #{name}}
=> ["hello", "world", "\#{name}"][17] pry(main)> %x{ls}
=> "debugtest.rb\ngrep.rb\ntest1.txt\ntest2.rb\ntest.py\ntest.rb\ntest.txt\n"[18] pry(main)> what_ruby = 'this is ruby'
=> "this is ruby"[19] pry(main)> %r{/home/#{what_ruby}}
=> /\/home\/this is ruby/[20] pry(main)> %s{hello}
=> :hello[21] pry(main)> %i{hello world}
=> [:hello, :world]

语法特点

括号

Ruby 语法特点是括号能去掉的它就去掉了(这种特点让他的语法更像是介于 Shell 和 Python之间),比如数组反转(print,puts, p之类),使用的时候可加可不加括号(不强制!如果你之前习惯了 Shell 的语法,你可能习惯性不加括号;如果你之前习惯了 Python3 的语法,你可能习惯性加上括号):

[136] pry(main)> names
=> ["I", "am", "Looking"]
[137] pry(main)> names.reverse
=> ["Looking", "am", "I"]
[138] pry(main)> names.reverse()
=> ["Looking", "am", "I"]
[139] pry(main)> names
=> ["I", "am", "Looking"]
[140] pry(main)> print "Hello World"
Hello World=> nil
[141] pry(main)> print("Hello World")
Hello World=> nil

就算括号实在不愿去掉或者实在没法去掉,也尽量让你少摁 ←键,比如就出现了下面这种 names.[]0 的骚操作:

[134] pry(main)> names
=> ["I", "am", "Looking"]
[142] pry(main)> names[0]
=> "I"
[135] pry(main)> names.[]0
=> "I"

而 Python 在 Python3 以后更加强调加括号表示调用,不加括号表示引用,所以在 Python3 以后的版本都不支持(不兼容) print "Hello World" 了,必须用 print("Hello World") 才可以。

[root@master ~]# python
Python 2.7.5 (default, Jun 20 2019, 20:27:34)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello World"
Hello World
>>>
[6]+  Stopped                 python
[root@master ~]# python3
Python 3.6.8 (default, Aug  7 2019, 17:28:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello World"File "<stdin>", line 1print "Hello World"^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("Hello World")?
>>>

end

Ruby另外一个特点应该就是那些个数不清的 end 了,当然 end 也不是Ruby独有的,像MATLAB之类的,语法也有这种特点(这样的话,代码是否能运行就不依赖于缩进了)。

! 和 ?

可以把它当做一种默认的约定的规范, 只是为了根据语意实现自释义,所以一般来说大家都愿意遵守这种规范。

“!”,这个符号通常情况下本身就有小心警告的意思。因此,方法调用如果使用没有叹号结尾的方法,你在调用它的时候会得到当前对象的一个拷贝而不会修改原始对象,而如果使用带有叹号的方法,你在调用它的时候会直接修改当前对象的值(这个时候要时刻提醒自己注意原对象的改变)。

[78] pry(main)> company_name = "Dunder Mifflin"
=> "Dunder Mifflin"
[79] pry(main)> company_name.upcase
=> "DUNDER MIFFLIN"
[80] pry(main)> company_name
=> "Dunder Mifflin"
[81] pry(main)> company_name.upcase!
=> "DUNDER MIFFLIN"
[82] pry(main)> company_name
=> "DUNDER MIFFLIN"[31] pry(main)> names = ["I", "am", "Looking"]
=> ["I", "am", "Looking"]
[32] pry(main)> names.reverse
=> ["Looking", "am", "I"]
[33] pry(main)> names
=> ["I", "am", "Looking"]
[34] pry(main)> names.reverse!
=> ["Looking", "am", "I"]
[35] pry(main)> names
=> ["Looking", "am", "I"]

“?”,被用于标示谓词,即返回Boolean值的方法,如Array.empty?(判断数组中元素是否为空),当然自己定义方法的时候如果返回布尔类型的话也可以加上“?”。

[84] pry(main)> array = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
[86] pry(main)> array.empty?
=> false# eg
[99] pry(main)> def success?(field)
[99] pry(main)*   field.size > 5 ? true : false
[99] pry(main)* end
=> nil
[100] pry(main)> success?([1, 2])
=> false
[101] pry(main)> success?([1, 2, 3, 4, 5, 6])
=> true
[103] pry(main)>

return

更严谨的说,Ruby 的方法也是尽可能不用 return,除非迫不得已(比如要提前返回一些东西)。有点像用括号一样,一般默认返回方法里边最后一个表达式的值。

# Ruby
def return_test"hello world""I am Looking"
endreturn_result = return_test
puts return_resultD:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
I am LookingProcess finished with exit code 0--------------------------------------------------------------------------------
def return_testreturn "hello world""I am Looking"
endreturn_result = return_test
puts return_resultD:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
hello worldProcess finished with exit code 0

当然,Python 也可以不用 return,除非你不需要函数返回任何东西。

# Python3
def return_test():"hello world""I am Looking"return_result = return_test()
print(return_result)"D:\Program Files\Python36\python3.exe" D:/MyProject/Python/workspace/test.py
NoneProcess finished with exit code 0--------------------------------------------------------------------------------
def return_test():return "hello world""I am Looking"return_result = return_test()
print(return_result)"D:\Program Files\Python36\python3.exe" D:/MyProject/Python/workspace/test.py
hello worldProcess finished with exit code 0

注释

单行注释都使用 # ,多行注释稍有差别

# Ruby
# This is a comment=begin
This is a multi-line comment.
The beginning line must start with "=begin"
and the ending line must start with "=end".You can do this, or start each line in
a multi-line comment with the # character.
=endputs "Hello World"
# Python
# Single line comments start with a number symbol."""
Multiline strings can be written
using three "s, and are often used
as documentation.
"""
print("Hello World")

基本四则运算

# Ruby
irb(main):011:0> 1
=> 1
irb(main):012:0> 100
=> 100
irb(main):013:0> 3.1415
=> 3.1415
irb(main):014:0> 1 + 1
=> 2
irb(main):015:0> 2 - 3
=> -1
irb(main):016:0> 5 * 10
=> 50
irb(main):017:0> 100 / 4
=> 25
irb(main):018:0> 20 + 8 / 2
=> 24
irb(main):019:0> (20 + 8) / 2
=> 14
irb(main):020:0> 2 ** 3
=> 8
irb(main):021:0> Math.sin(3.1415)
=> 9.265358966049026e-05
irb(main):022:0> Math.sqrt(10000)
=> 100.0
# Python3
>>> 1
1
>>> 100
100
>>> 3.1415
3.1415
>>> 1 + 1
2
>>> 2 - 3
-1
>>> 5 * 10
50
>>> 100 / 4
25.0
>>> 20 + 8 / 2
24.0
>>> (20 + 8) / 2
14.0
>>> 2 ** 3
8
>>> math.sin(3.1415)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> import math
>>> math.sin(3.1415)
9.265358966049026e-05
>>> math.sqrt(10000)
100.0

变量和对象

# Ruby
[1] pry(main)> true
=> true
[2] pry(main)> false
=> false
[3] pry(main)> nil
=> nil
[4] pry(main)> true.class
=> TrueClass
[5] pry(main)> false.class
=> FalseClass
[6] pry(main)> nil.class
=> NilClass
[11] pry(main)> !false
=> true
[12] pry(main)> !!false
=> false
[13] pry(main)> !true
=> false
[14] pry(main)> !!true
=> true
[15] pry(main)> !nil
=> true
[16] pry(main)> !!nil
=> false
[17] pry(main)> !0
=> false
[18] pry(main)> !!0
=> true
[19] pry(main)> !""
(pry):19: warning: string literal in condition
=> false
[20] pry(main)> !!""
(pry):20: warning: string literal in condition
=> true
[23] pry(main)> "hello " << "world"
=> "hello world"
[24] pry(main)> "hello " + "world"
=> "hello world"[11] pry(main)> # 变量的作用域通过我们对它的命名进行定义
[12] pry(main)> # 以 $ 开头的变量为全局变量
[13] pry(main)> $var = "I'm a global var"
=> "I'm a global var"
[14] pry(main)> defined? $var #=> "global-variable"
=> "global-variable"
[15] pry(main)>
[16] pry(main)> # 以 @ 开头的变量为实例变量
[17] pry(main)> @var = "I'm an instance var"
=> "I'm an instance var"
[18] pry(main)> defined? @var #=> "instance-variable"
=> "instance-variable"
[19] pry(main)>
[20] pry(main)> # 以 @@ 开头的变量为类变量
[21] pry(main)> @@var = "I'm a class var"
=> "class variable"
[30] pry(main)> defined? @@var #=> "class variable"
=> "class variable"
[23] pry(main)>
[24] pry(main)> # 以大写字母开头的为常量
[25] pry(main)> Var = "I'm a constant"
=> "I'm a constant"
[26] pry(main)> defined? Var
=> "constant"
# Python3
>>> True
True
>>> False
False
>>> None
>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>
>>> type(None)
<class 'NoneType'>
>>> not False
True
>>> not not False
False
>>> not True
False
>>> not not True
True
>>> not None
True
>>> not not None
False
>>> "hello " + "world"
'hello world'

比较运算

# Ruby
irb(main):022:0> 2 == 2
=> true
irb(main):023:0> 1 == 2
=> false
irb(main):024:0> 3 > 1
=> true
irb(main):025:0> 3 > 3
=> false
irb(main):026:0> 3 >= 3
=> true
irb(main):027:0> 3 < 1
=> false
irb(main):028:0> 3 < 3
=> false
irb(main):029:0> 3 <= 3
=> true
irb(main):030:0> "Ruby" == "Ruby"
=> true
irb(main):031:0> "Ruby" == "Python"
=> false
irb(main):032:0> 1 != 1
=> false
# Python3
>>> 2 == 2
True
>>> 1 == 2
False
>>> 3 > 1
True
>>> 3 > 3
False
>>> 3 >= 3
True
>>> 3 < 1
False
>>> 3 < 3
False
>>> 3 <= 3
True
>>> "Python" == "Python"
True
>>> "Python" == "Ruby"
False
>>> 1 != 1
False

添加判断

# Ruby
[71] pry(main)> if true
[71] pry(main)*   'if statement'
[71] pry(main)* elsif false
[71] pry(main)*   'else if, optional'
[71] pry(main)* else
[71] pry(main)*   'else, also optional'
[71] pry(main)* end
=> "if statement"irb(main):033:0> a = 20
=> 20
[22] pry(main)> if a >= 10
[22] pry(main)*   puts "bigger"
[22] pry(main)* else
[22] pry(main)*   puts "smaller"
[22] pry(main)* end
bigger
=> nil# 当然,对Ruby来说,缩进不缩进都无所谓啦,毕竟人家又不靠缩进吃饭,即使你像下面这么些也还是可以正常执行
# 不过,为了可读性,最好不要这么做啦!
irb(main):039:0> if a >= 10
irb(main):040:1> print "bigger"
irb(main):041:1> else
irb(main):042:1* print "smaller"
irb(main):043:1> end
bigger=> nil
irb(main):044:0> 
# Python3
# 记得一定要缩进哟
>>> if True:
...     'if statement'
... elif False:
...     'else if, optional'
... else:
...     'else, also optional'
...
'if statement'>>> a = 20
>>> if a >= 10:
...     print("bigger")
... else:
...     print("smaller")
...
bigger

循环比较

# Ruby
irb(main):044:0> i = 1
=> 1
irb(main):045:0> while i <= 10
irb(main):046:1>     puts i
irb(main):047:1>     i += 1
irb(main):048:1> end
1
2
3
4
5
6
7
8
9
10
=> nil
------------------------------------------------------------
irb(main):049:0> 10.times do
irb(main):050:1*    puts "Hello World"
irb(main):051:1> end
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
=> 10
# Python3
>>> i = 1
>>> while i <= 10:
...     print(i)
...     i += 1
...
1
2
3
4
5
6
7
8
9
10
------------------------------------------------------------
>>> i = 1
>>> while i <= 10:
...     print("Hello World")
...     i += 1
...
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World

数组(列表)比较及元素遍历

数组字面量通过[]中以逗号分隔定义,且支持range定义。

  • (1)数组通过[]索引访问
  • (2)通过赋值操作插入、删除、替换元素
  • (3)通过+,-号进行合并和删除元素,且集合做为新集合出现
  • (4)通过<<号向原数据追加元素
  • (5)通过*号重复数组元素
  • (6)通过|和&符号做并集和交集操作(注意顺序)
# Ruby
irb(main):052:0> names = ["I", "am", "Looking"]
=> ["I", "am", "Looking"]
irb(main):053:0> names[0]
=> "I"
[26] pry(main)> names.first
=> "I"
[64] pry(main)> names.[] 0  # 这个操作确实有点骚
=> "I"
irb(main):054:0> names[0] = "i"
=> "i"
irb(main):055:0> names
=> ["i", "am", "Looking"]
[27] pry(main)> names.last
=> "Looking"
[28] pry(main)> names[-1]
=> "Looking"
[66] pry(main)> names << "!"
=> ["I", "am", "Looking", "!"]
[67] pry(main)> names.push("!")
=> ["I", "am", "Looking", "!", "!"]
[70] pry(main)> names.include?("Looking")
=> trueirb(main):056:0> names.size
=> 3
irb(main):057:0> names.length
=> 3[55] pry(main)> names
=> ["I", "am", "Looking"]
[56] pry(main)> names.reverse # 不会修改原数组
=> ["Looking", "am", "I"]
[57] pry(main)> names
=> ["I", "am", "Looking"]
[58] pry(main)> names.reverse! # 会修改原数组
=> ["Looking", "am", "I"]
[59] pry(main)> names
=> ["Looking", "am", "I"]irb(main):058:0> names.each do |name|
irb(main):059:1*     puts name
irb(main):060:1> end
i
am
Looking
=> ["i", "am", "Looking"][85] pry(main)> names.each_with_index do |element, index|
[85] pry(main)*   puts "#{element} is number #{index} in the array"
[85] pry(main)* end
I is number 0 in the array
am is number 1 in the array
Looking is number 2 in the array
=> ["I", "am", "Looking"]irb(main):064:0> names.each {
irb(main):065:1*     puts "Hello World"
irb(main):066:1> }
Hello World
Hello World
Hello World
=> ["i", "am", "Looking"]irb(main):067:0> names.each do
irb(main):068:1*     puts "Hello World"
irb(main):069:1> end
Hello World
Hello World
Hello World
=> ["i", "am", "Looking"]
# Python3
>>> names = ["I", "am", "Looking"]
>>> names[0]
'I'
>>> names[0] = "i"
>>> names
['i', 'am', 'Looking']
>>> names[-1]
'Looking'
>>> len(names)
3>>> names
['I', 'am', 'Looking']
>>> names.reverse() # 会修改原列表元素顺序
>>> names
['Looking', 'am', 'I']>>> names = ["I", "am", "Looking"]
>>> names.append("!")
>>> names
['I', 'am', 'Looking', '!']
>>> "Looking" in names
True>>> for name in names:
...     print(name)
...
i
am
Looking>>> for index, element in enumerate(names):
...     print(f"{element} is number {index} in the array")
...
I is number 0 in the array
am is number 1 in the array
Looking is number 2 in the array>>> for name in names:
...     print("Hello World")
...
Hello World
Hello World
Hello World

散列(字典)比较

# Ruby
# Ruby当中符号也可以作为
irb(main):071:0> address = {name:"Looking", pinyin:"lukaiyi", postal:"405902"}
=> {:name=>"Looking", :pinyin=>"lukaiyi", :postal=>"405902"}
irb(main):074:0* address = {:name=>"Looking", :pinyin=>"lukaiyi", :postal=>"405902"}
=> {:name=>"Looking", :pinyin=>"lukaiyi", :postal=>"405902"}
irb(main):014:0> address[:name]
=> "Looking"
irb(main):015:0> address["name".to_sym]
=> "Looking"
irb(main):016:0> # Ruby在好些地方加括号和不加括号区别不大,就比如 print, puts, p
# Python则不一样,加括号表示调用,不加括号表示引用,指向函数代码所在的地址
[73] pry(main)> address.keys
=> ["name", "pinyin", "postal"]
[74] pry(main)> address.keys()
=> ["name", "pinyin", "postal"]
[75] pry(main)> address.values
=> ["Looking", "lukaiyi", "405902"]irb(main):007:0> address = {"name"=>"Looking", "pinyin"=>"lukaiyi", "postal"=>"405902"}
=> {"name"=>"Looking", "pinyin"=>"lukaiyi", "postal"=>"405902"}
irb(main):011:0> address["name"]
=> "Looking"
irb(main):012:0> address[:name.to_s]
=> "Looking"irb(main):016:0> sym = :foo
=> :foo
irb(main):017:0> sym.to_s
=> "foo"
irb(main):018:0> "foo"
=> "foo"
irb(main):019:0> "foo".to_sym
=> :fooirb(main):021:0> address[:tel] = "123456789"
=> "123456789"
irb(main):022:0> address
=> {:name=>"Looking", :pinyin=>"lukaiyi", :postal=>"405902", :tel=>"123456789"}irb(main):023:0> address.each do |key, value|
irb(main):024:1*    puts "#{key}: #{value}"
irb(main):025:1> end
name: Looking
pinyin: lukaiyi
postal: 405902
tel: 123456789
=> {:name=>"Looking", :pinyin=>"lukaiyi", :postal=>"405902", :tel=>"123456789"}
# Python3
# Python3 字典的 key 需要可哈希化
>>> address = {"name": "Looking", "pinyin":"lukaiyi", "postal":"405902"}
>>> address
{'name': 'Looking', 'pinyin': 'lukaiyi', 'postal': '405902'}
>>> address = dict(name="Looking", pinyin="lukaiyi", postal="405902")
>>> address
{'name': 'Looking', 'pinyin': 'lukaiyi', 'postal': '405902'}# Ruby在好些地方加括号和不加括号区别不大,但是Python对这块倒是区分得很严格的
# Python加括号表示调用,不加括号表示引用,指向函数代码所在的地址
>>> address.keys()
dict_keys(['name', 'pinyin', 'postal'])
>>> address.keys
<built-in method keys of dict object at 0x7f3af9f405a0>
>>> address.values()
dict_values(['Looking', 'lukaiyi', '405902'])
>>> address.values
<built-in method values of dict object at 0x7f3af9f405a0>>>> address["tel"] = "123456789"
>>> address
{'name': 'Looking', 'pinyin': 'lukaiyi', 'postal': '405902', 'tel': '123456789'}>>> for key, value in address.items():
...     print(key, ":", value)
...
name : Looking
pinyin : lukaiyi
postal : 405902
tel : 123456789

字符串与模式匹配

# Ruby
irb(main):026:0> /cde/ =~ "abcdefgh"
=> 2
irb(main):027:0> /Cde/ =~ "abcdefgh"
=> nil
irb(main):028:0> /Cde/i =~ "abcdefgh"
=> 2
irb(main):029:0> /Cde/i =~ "abcdEfgh"
=> 2irb(main):031:0> names = ["Looking", "Luck", "John"]
=> ["Looking", "Luck", "John"]
irb(main):032:0> names.each do |name|
irb(main):033:1*   if /o/ =~ name
irb(main):034:2>     puts name
irb(main):035:2>   end
irb(main):036:1> end
Looking
John
=> ["Looking", "Luck", "John"]
# Python3
>>> "abcdefgh".find("cde")
2
>>> "abcdefgh".find("Cde")
-1
>>> "abcdefgh".find("Cde".lower())
2
>>> "abcdefgh".lower().find("Cde".lower())
2>>> names = ["Looking", "Luck", "John"]
>>> for name in names:
...     if 'o' in name:
...             print(name)
...
Looking
John

变量比较

变量在使用之前都需要先赋值,这应该是它们的相同点了。

# Rubysub.rb
$x = 1 #对全局变量赋值
x = 1 #对本地量赋值test.rb
$x = 0
x = 0
require './sub'
p $x
p xD:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
1
0Process finished with exit code 0------------------------------------------------------------
irb(main):037:0> x + 1
NameError: undefined local variable or method `x' for main:Objectfrom (irb):37from /usr/bin/irb:12:in `<main>'# Ruby使用全大写来表示常量,常量重新赋值的话还会报警告消息。
irb(main):038:0> TEST = 1
=> 1
irb(main):039:0> TEST = 2
(irb):39: warning: already initialized constant TEST
(irb):38: warning: previous definition of TEST was here
=> 2
------------------------------------------------------------
# 保留字重新赋值会提示语法错误,Python3也不例外
irb(main):041:0> if = 1
SyntaxError: (irb):41: syntax error, unexpected '='
if = 1^from /usr/bin/irb:12:in `<main>'
------------------------------------------------------------
irb(main):043:0> a, b, c = 1, 2, 3
=> [1, 2, 3]
irb(main):044:0> a, b, c = 1, 2, 3, 4
=> [1, 2, 3, 4]
irb(main):045:0> c
=> 3
irb(main):046:0> a, b, *c = 1, 2, 3, 4
=> [1, 2, 3, 4]
irb(main):047:0> a, b = b, a
=> [2, 1]
irb(main):048:0> c
=> [3, 4]
# Python3
>>> x + 1
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
------------------------------------------------------------
# Python3一般也使用全大写来表示常量,但是你要改的话就该,反正不关我们Python的事儿,我就当你知道你在做什么就是了。
>>> TEST = 1
>>> TEST = 2
------------------------------------------------------------
>>> if = 1File "<stdin>", line 1if = 1^
SyntaxError: invalid syntax
------------------------------------------------------------
>>> a, b, c = 1, 2, 3
>>> a, b, c = 1, 2, 3, 4
Traceback (most recent call last):File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)
>>> a, b, *c = 1, 2, 3, 4
>>> a, b
(1, 2)
>>> a, b = b, a
>>> a, b
(2, 1)
>>> c
[3, 4]

常用循环函数

# Ruby
[87] pry(main)> doubled = array.map do |element|
[87] pry(main)*   element * 2
[87] pry(main)* end
=> [2, 4, 6, 8, 10]
[91] pry(main)> array.map {|s| s. * 2}
=> [2, 4, 6, 8, 10]
[93] pry(main)> array.inject(0) {|sum, n| sum + n } # 括号的0表示sum的初始值,可不写,不写的时候括号也可以去掉
=> 15
[92] pry(main)> array.reduce(:+)
=> 15[98] pry(main)> a = ["FOO", "BAR", "BAZ"]
=> ["FOO", "BAR", "BAZ"]
[99] pry(main)> a.map{|s| s.downcase}
=> ["foo", "bar", "baz"]
[100] pry(main)> a.map(&:downcase)
=> ["foo", "bar", "baz"]
[101] pry(main)> a
=> ["FOO", "BAR", "BAZ"]
# Python3
>>> [ 2*x for x in array]
[2, 4, 6, 8, 10]
>>> array = [1, 2, 3, 4, 5]
>>> list(map(lambda x: 2*x, array))
[2, 4, 6, 8, 10]
>>> list(filter(lambda x: x>3, array))
[4, 5]
>>> from functools import reduce
>>> reduce(lambda x, y: x + y, array)
15
>>> a = ["FOO", "BAR", "BAZ"]
>>> [x.lower() for x in a]
['foo', 'bar', 'baz']
>>> list(map(lambda x:x.lower(), a))
['foo', 'bar', 'baz']
>>> a
['FOO', 'BAR', 'BAZ']

unless,case,until 结构

对不起,Python 表示我没这些花里胡哨的东东,直接用 not 它不香吗?多出的这些单词大家不认识怎么办?(/哈哈)

# Ruby
[102] pry(main)> a = 10
=> 10
[103] pry(main)> b = 20
=> 20
[104] pry(main)> unless a > b
[104] pry(main)*   puts "a not greater than b"
[104] pry(main)* else
[104] pry(main)*   puts "a greater than b"
[104] pry(main)* end
a not greater than b
=> nil
------------------------------------------------------------
[105] pry(main)> grade = 82
=> 82
[106] pry(main)> case grade
[106] pry(main)* when 90..100
[106] pry(main)*   puts 'Hooray!'
[106] pry(main)* when 80...90
[106] pry(main)*   puts 'OK job'
[106] pry(main)* else
[106] pry(main)*   puts 'You failed!'
[106] pry(main)* end
OK job
=> nil# 注意 m..n 语法的细节哟!中间两个点表示包含左右两端的数,三个点的话不包含右边的数哟!
[113] pry(main)> (80..90).include?(80)
=> true
[114] pry(main)> (80..90).include?(90)
=> true
[119] pry(main)> (80...90).include?(80)
=> true
[120] pry(main)> (80...90).include?(90)
=> false
------------------------------------------------------------
[121] pry(main)> sum = 0
=> 0
[122] pry(main)> i = 1
=> 1
[123] pry(main)> while sum < 50
[123] pry(main)*   sum += i
[123] pry(main)*   i += 1
[123] pry(main)* end
=> nil
[124] pry(main)> puts sum
55
=> nil[125] pry(main)> sum = 0
=> 0
[126] pry(main)> i = 1
=> 1
[127] pry(main)> until sum >= 50
[127] pry(main)*   sum += i
[127] pry(main)*   i += 1
[127] pry(main)* end
=> nil
[128] pry(main)> puts sum
55
=> nil
# Python3
>>> if not a > b:
...     print("a not greater than b")
... else:
...     print("a greater than b")
...
a not greater than b
------------------------------------------------------------
>>> grade = 82
>>> if 90 <= grade <= 100:
...     print('Hooray!')
... elif 80 <= grade < 90:
...     print('OK job')
... else:
...     print('You failed!')
...
OK job------------------------------------------------------------
# Ruby 里边有的说用 not 不直观,反正我真的没看出来哪点不直观
>>> sum = 0
>>> i = 1
>>> while not sum >= 50:
...     sum += i
...     i += 1
...
>>> print(sum)
55

异常处理

两种语言异常处理的对应关系大家自己慢慢看哟,除了名字意外,其实也差不错的。

# Ruby
[148] pry(main)> begin
[148] pry(main)*   # Code here that might raise an exception
[148] pry(main)*   raise NoMemoryError, 'You ran out of memory.'
[148] pry(main)* rescue NoMemoryError => exception_variable
[148] pry(main)*   puts 'NoMemoryError was raised', exception_variable
[148] pry(main)* rescue RuntimeError => other_exception_variable
[148] pry(main)*   puts 'RuntimeError was raised now'
[148] pry(main)* else
[148] pry(main)*   puts 'This runs if no exceptions were thrown at all'
[148] pry(main)* ensure
[148] pry(main)*   puts 'This code always runs no matter what'
[148] pry(main)* end
NoMemoryError was raised
You ran out of memory.
This code always runs no matter what
=> nil
# Python3
>>> try:
...     # Code here that might raise an exception
...     raise MemoryError('Your ran out of memory.')
... except MemoryError as exception_variable:
...     print("MemoryError was raised", exception_variable, sep='\n')
... except RuntimeError as other_exception_variable:
...     print("RuntimeError was raised now")
... else:
...     print("This runs if no exceptions were thrown at all")
... finally:
...     print("This code always runs no matter what")
...
MemoryError was raised
Your ran out of memory.
This code always runs no matter what

方法(函数)

# Ruby
[1] pry(main)> def double(x)
[1] pry(main)*   x * 2
[1] pry(main)* end
=> nil
[2] pry(main)> double(2)
=> 4
[3] pry(main)> double 3
=> 6
[4] pry(main)> double double 3
=> 12 [1] pry(main)> def sum(x, y)
[1] pry(main)*   x + y
[1] pry(main)* end
=> nil
[2] pry(main)> sum 3, 4
=> 7
[3] pry(main)> sum sum(3, 4), 5
=> 12[4] pry(main)> def surround
[4] pry(main)*   puts '{'
[4] pry(main)*   yield
[4] pry(main)*   puts '}'
[4] pry(main)* end
=> nil
[5] pry(main)>
[6] pry(main)> surround { puts 'hello world' }
{
hello world
}
=> nil
# 这儿对块简单的理解就是在原来 yield 的地方执行了块里边的语句
# yield 后边如果有参数的话,也可以传递到块里边去
[34] pry(main)> def guests
[34] pry(main)*   yield 4
[34] pry(main)* end
=> nil
[35] pry(main)> guests{|n| "You have #{n} guests."}
=> "You have 4 guests."# 但是如果方法的最后一个参数前带有 &,那么您可以向该方法传递一个块。
# 而且这个块可被赋给最后一个参数。如果 * 和 & 同时出现在参数列表中,& 应放在后面。
[23] pry(main)> def guests(&block)
[23] pry(main)*   block.call(4)
[23] pry(main)* end
=> nil
[24] pry(main)> guests{|n| "You have #{n} guests."}
=> "You have 4 guests."
# Python3
>>> def double(x):
...     return x * 2
...
>>> double(2)
4
>>> double(3)
6
>>> double(double(3))
12>>> def sum(x, y):
...     return x + y
...
>>> sum(3, 4)
7
>>> sum(sum(3, 4), 5)
12

参数的匹配和解包

这块这两种语言用法是类似的

# Ruby
# 当 * 和 ** 符号出现在函数定义的参数中时,表示任意数目参数收集
[39] pry(main)> def guests(*array)
[39] pry(main)*   array.each { |guest| puts guest }
[39] pry(main)* end
=> nil[42] pry(main)> guests('hello', 'world')
hello
world
=> ["hello", "world"]# * 和 ** 符号出现在函数调用的参数中时,表示会解包参数的集合
[44] pry(main)> def guests(a, b, c, d)
[44] pry(main)*   puts a, b, c, d
[44] pry(main)* end
=> nil[46] pry(main)> guests(*['hello', 'world', 'ruby', 'python'])
hello
world
ruby
python
=> nil# 解包和匹配合体示例
[1] pry(main)> def best(first, second, third, *others)
[1] pry(main)*   puts "Winners are #{first}, #{second}, and #{third}."
[1] pry(main)*   puts "There were #{others.count} other participants."
[1] pry(main)* end
=> nil
[2] pry(main)> ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
=> ["John", "Sally", "Dingus", "Moe", "Marcy"]
[3] pry(main)> best *ranked_competitors
Winners are John, Sally, and Dingus.
There were 2 other participants.
=> nil
# Python3
>>> def guests(*array):
...     for guest in array:
...             print(guest)
... # 当 * 和 ** 符号出现在函数定义的参数中时,表示任意数目参数收集
>>> guests('hello', 'world')
hello
world>>> def guests(a, b, c, d):
...     print(a, b, c, d, sep='\n')
... # * 和 ** 符号出现在函数调用的参数中时,表示会解包参数的集合
>>> guests(*['hello', 'world', 'ruby', 'python'])
hello
world
ruby
python# 解包和匹配合体示例
>>> def best(first, second, third, *others):
...     print(f"Winners are, {first}, {second} and {third}.")
...     print(f"There were {len(others)} other participants.")
...
>>> best(*ranked_competitors)
Winners are, John, Sally and Dingus.
There were 2 other participants.

map,reduce 和 select(filter)

# Ruby
[50] pry(main)> array  = ['Watch', 'these', 'words', 'get', 'upcased']
=> ["Watch", "these", "words", "get", "upcased"]
[51] pry(main)> array.map(&:upcase)
=> ["WATCH", "THESE", "WORDS", "GET", "UPCASED"]
[52] pry(main)> array.map do |item|
[52] pry(main)*   item.upcase!
[52] pry(main)* end
=> ["WATCH", "THESE", "WORDS", "GET", "UPCASED"][57] pry(main)> array = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
[59] pry(main)> sum = array.reduce(&:+)
=> 15
[60] pry(main)> multiplication = array.reduce(&:*)
=> 120
[61] pry(main)> [67] pry(main)> array = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
[68] pry(main)> array.select{|x| x < 4}
=> [1, 2, 3]
# Python3
>>> array  = ['Watch', 'these', 'words', 'get', 'upcased']
>>> array
['Watch', 'these', 'words', 'get', 'upcased']
>>> list(map(lambda x: x.upper(), array))
['WATCH', 'THESE', 'WORDS', 'GET', 'UPCASED']>>> from functools import reduce
>>> array = [1, 2, 3, 4, 5]
>>> sum = reduce(lambda x, y: x + y, array)
>>> sum
15
>>> multiplication = reduce(lambda x, y: x * y, array)
>>> multiplication
120>>> array = [1, 2, 3, 4, 5]
>>> list(filter(lambda x: x < 4, array))
[1, 2, 3]

Ruby 里边可以有相同类名的类(会对里边的内容自动进行扩展):

class HelloWorlddef instance_methodputs "instance method"end
endclass HelloWorlddef testputs "test"end
endHelloWorld.new.instance_method
HelloWorld.new.test

Python 里边不可以有相同类名的类(或者说可以有相同的,但是后定义的类会覆盖掉先定义的):

class HelloWorld:def instance_method(self):print('instance method')class HelloWorld:def test(self):print("test")HelloWorld().instance_method()    # AttributeError: 'HelloWorld' object has no attribute 'instance_method'
HelloWorld().test()

在类方面,Ruby 和 Python 还有一个很大的不同:如果 Ruby 的类里边没有实现某个实例变量的 set 和 get 方法的话,从对象外部不能直接访问实例变量或对实例变量进行赋值。

# Ruby
class Human# 类变量,被类的所有实例共享@@species = 'H. sapiens'# 初始化def initialize(name, age = 0)# 实例变量初始化, 实例变量无法脱离方法进行声明和定义@name = name# 如果 age 没有,取默认值@age = ageend# set 方法def name=(name)@name = nameend# get 方法def name@nameend# attr_accessor相当于attr_reader和attr_writer的合集,实际上是在定义类成员变量的时候就给他定义了一个get和set方法。attr_accessor :age# 在ruby中,类成员变量都是私有的,不能直接通过(类名.成员变量名)这样来对成员变量值进行操作。# get/set 方法也可以像下面这么单独创建,如果没有创建的话,不能按照如下这样使用:# 实例对象.age# 实例对象.age = 2attr_reader :age # getattr_writer :age # setdef say_something(msg) # 实例方法puts msgend# 类方法通过 self 与实例方法进行区分,只能通过类进行调用def self.say(msg)puts msgend# 可以通过类方法或者实例方法修改类变量# 实例方法def modify_species(new_species)@@species = new_speciesenddef species@@speciesend
end# Instantiating of a class
jim = Human.new('Jim Halpert')
dwight = Human.new('Dwight K. Schrute')# You can call the methods of the generated object.
puts jim.species #=> "H. sapiens"
puts jim.name #=> "Jim Halpert"
jim.name = "Jim Halpert II" #=> "Jim Halpert II"
puts jim.name #=> "Jim Halpert II"
puts dwight.species #=> "H. sapiens"
puts dwight.name #=> "Dwight K. Schrute"# 调用类方法
Human.say('Hi') #=> "Hi"
jim.say_something("Hello") #=> "Hello"
jim.modify_species("animals")
puts jim.species #=> "animals"
jim.modify_species("H. sapiens")
puts jim.species #=> "H. sapiens"
puts jim.age #=> 0
jim.age = 5
puts jim.age #=> 5
# Python3
class Human:# 类属性,被类的所有实例共享species = "H. sapiens"def __init__(self, name, age=0):self.name = nameself._age = age# An instance method. All methods take "self" as the first argumentdef say(self, msg):print("{name}: {message}".format(name=self.name, message=msg))# Another instance methoddef sing(self):return 'yo... yo... microphone check... one two... one two...'# A class method is shared among all instances# They are called with the calling class as the first argument@classmethoddef get_species(cls):return cls.species# A static method is called without a class or instance reference@staticmethoddef grunt():return "*grunt*"# A property is just like a getter.# It turns the method age() into an read-only attribute of the same name.# There's no need to write trivial getters and setters in Python, though.@property  # getterdef age(self):return self._age# This allows the property to be set@age.setterdef age(self, age):self._age = age# This allows the property to be deleted@age.deleterdef age(self):del self._age# 当 Python 解释器读取一个源码文件时,它会执行其中所有代码
# 用 __name__ 确保这个代码块只有为主程序时才执行。
if __name__ == '__main__':i = Human(name="Ian")i.say("hi")  # "Ian: hi"j = Human("Joel")j.say("hello")  # "Joel: hello"i.say(i.get_species())  # "Ian: H. sapiens"Human.species = "H. neanderthalensis"i.say(i.get_species())  # => "Ian: H. neanderthalensis"j.say(j.get_species())  # => "Joel: H. neanderthalensis"# 通过类调用静态方法print(Human.grunt())  # => "*grunt*"# 通过实例对象调用静态方法print(i.grunt())  # => "*grunt*"# 更新实例属性i.age = 42# 获取属性i.say(i.age)  # => "Ian: 42"j.say(j.age)  # => "Joel: 0"# 删除属性del i.age--------------------------------------------------------------------------------
class Human:species = 'H. sapiens'def __init__(self, name, age=0):self.name = nameself.age = age# 实例方法,第一个参数需要是self,它表示一个具体的实例对象本身,因为方法可能用的实例本身的一些变量def instance_method(self):print(f"Hello, I am instance_method, my name is {self.name}")# 如果用staticmethod装饰,那么就可以无视这个self,而将这个方法当成一个普通的函数使用@staticmethoddef static_method():print("Hello, I am static_method")return "Hello, I am static_method"# 如果用classmethod,它的第一个参数是cls,它表示这个类本身,可以通过类名进行调用# 可在类方法中使用静态方法@classmethoddef class_method(cls):print(cls.static_method() + " called by class_method")print("Hello, I am class_method")jim = Human('Jim Halpert')
dwight = Human('Dwight K. Schrute')
print(jim.species)
print(Human.species)
jim.instance_method()
jim.static_method()
Human.static_method()
Human.class_method()"D:\Program Files\Python36\python3.exe" D:/MyProject/Python/workspace/test.py
H. sapiens
H. sapiens
Hello, I am instance_method, my name is Jim Halpert
Hello, I am static_method
Hello, I am static_method
Hello, I am static_method
Hello, I am static_method called by class_method
Hello, I am class_methodProcess finished with exit code 0

子类

# Ruby
# 基类
class Human@@foo = 0# 下面这两个函数类似于类变量的 get/set 方法def self.foo@@fooenddef self.foo=(value)@@foo = valueend
end# 派生类(子类)
class Worker < Human
endputs Human.foo #=> 0
puts Worker.foo #=> 0# 类变量被它的所有子类共享
puts Human.foo = 2
puts Worker.foo #=> 2--------------------------------------------------------------------------------
class Human@bar = 0def self.bar@barenddef self.bar=(value)@bar = valueend
endclass Doctor < Human
end# 类实例变量不被子类所共享
Human.bar #=> 0
Doctor.bar #=> nil
# Python3
class Human:# 类属性,被类的所有实例共享species = "H. sapiens"def __init__(self, name, age=0):self.name = nameself._age = age# An instance method. All methods take "self" as the first argumentdef say(self, msg):print("{name}: {message}".format(name=self.name, message=msg))# Another instance methoddef sing(self):return 'yo... yo... microphone check... one two... one two...'# A class method is shared among all instances# They are called with the calling class as the first argument@classmethoddef get_species(cls):return cls.species# A static method is called without a class or instance reference@staticmethoddef grunt():return "*grunt*"# A property is just like a getter.# It turns the method age() into an read-only attribute of the same name.# There's no need to write trivial getters and setters in Python, though.@property  # getterdef age(self):return self._age# This allows the property to be set@age.setterdef age(self, age):self._age = age# This allows the property to be deleted@age.deleterdef age(self):del self._ageclass Superhero(Human):species = 'Superhuman'def __init__(self, name, movie=False,superpowers=["super strength", "bulletproofing"]):# add additional class attributes:self.fictional = Trueself.movie = movie# be aware of mutable default values, since defaults are sharedself.superpowers = superpowerssuper().__init__(name)  # 调用父类的初始化函数# override the sing methoddef sing(self):return 'Dun, dun, DUN!'# add an additional instance methoddef boast(self):for power in self.superpowers:print("I wield the power of {pow}!".format(pow=power))if __name__ == '__main__':sup = Superhero(name="Tick")# Instance type checksif isinstance(sup, Human):print('I am human')  # 超级英雄也是人,所以实例化的对象仍然是父类的一个实例if type(sup) is Superhero:print('I am a superhero')# 子类会优先去自己类本身找相应的方法和属性,找不到才到父类继续寻找print(sup.get_species())  # => Superhuman# Calls overridden methodprint(sup.sing())  # => Dun, dun, DUN!# Calls method from Humansup.say('Spoon')  # => Tick: Spoon# Call method that exists only in Superherosup.boast()  # => I wield the power of super strength!# => I wield the power of bulletproofing!# Inherited class attributesup.age = 31print(sup.age)  # => 31# Attribute that only exists within Superheroprint('Am I Oscar eligible? ' + str(sup.movie))

module

简单理解你就把他当成一个 namespace (命名空间),这样在调用的时候不至于太混乱。

# Ruby
# trig.rb
module TrigPI = 3.141592654def Trig.sin(x)Math.sin(x)enddef Trig.cos(x)Math.cos(x)end
end--------------------------------------------------------------------------------
# moral.rb
module MoralVERY_BAD = 0BAD = 1def Moral.sin(badness)Math.sin(badness)end
end--------------------------------------------------------------------------------
# test.rb
$LOAD_PATH << '.'
# $LOAD_PATH << '.' 让 Ruby 知道必须在当前目录中搜索被引用的文件
require 'trig.rb'
require 'moral'y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)
puts y, wrongdoingD:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
0.7071067812590626
0.0Process finished with exit code 0--------------------------------------------------------------------------------
# Ruby
module ModuleExampledef foo'foo'end
end# include modules 将他们的方法和类实例进行绑定(也即只能通过生成的实例来进行调用)
# extend modules 将他们的方法和类本身进行绑定 (也即只能通过类本身进行调用)
class Personinclude ModuleExample
endclass Bookextend ModuleExample
endputs Person.foo     #=> NoMethodError: undefined method `foo' for Person:Class
puts Person.new.foo #=> "foo"
puts Book.foo       #=> "foo"
puts Book.new.foo   #=> NoMethodError: undefined method `foo'--------------------------------------------------------------------------------
module ConcernExampledef self.included(base)base.extend(ClassMethods)base.send(:include, InstanceMethods)endmodule ClassMethodsdef bar'bar'endendmodule InstanceMethodsdef qux'qux'endend
endclass Somethinginclude ConcernExample
endputs Something.bar     #=> "bar"
puts Something.qux     #=> NoMethodError: undefined method `qux'
puts Something.new.bar #=> NoMethodError: undefined method `bar'
puts Something.new.qux #=> "qux"

JSON文件解析

新建 input.json 文件

# input.json{"President": "Alan Isaac","CEO": "David Richardson","India": ["Sachin Tendulkar","Virender Sehwag","Gautam Gambhir"],"Srilanka": ["Lasith Malinga","Angelo Mathews","Kumar Sangakkara"],"England": ["Alastair Cook","Jonathan Trott","Kevin Pietersen"]
}
# Ruby
[1] pry(main)> require 'json'
=> true
[2] pry(main)> require 'pp'
=> false
[3] pry(main)> json = File.read('input.json')
=> "{\n  \"President\": \"Alan Isaac\",\n  \"CEO\": \"David Richardson\",\n  \n  \"India\": [\n    \"Sachin Tendulkar\",\n    \"Virender Sehwag\",\n    \"Gautam Gambhir\"\n  ],\n \n  \"Srilanka\": [\n    \"Lasith Malinga\",\n    \"Angelo Mathews\",\n    \"Kumar Sangakkara\"\n  ],\n \n  \"England\": [\n    \"Alastair Cook\",\n    \"Jonathan Trott\",\n    \"Kevin Pietersen\"\n  ]\n}\n"
[4] pry(main)> obj = JSON.parse(json)
=> {"President"=>"Alan Isaac","CEO"=>"David Richardson","India"=>["Sachin Tendulkar", "Virender Sehwag", "Gautam Gambhir"],"Srilanka"=>["Lasith Malinga", "Angelo Mathews", "Kumar Sangakkara"],"England"=>["Alastair Cook", "Jonathan Trott", "Kevin Pietersen"]}
[5] pry(main)> obj['President']
=> "Alan Isaac"
# Python3
>>> import json
>>> with open('input.json', 'r') as f:
...     data = json.load(f)
...
>>> data
{'President': 'Alan Isaac', 'CEO': 'David Richardson', 'India': ['Sachin Tendulkar', 'Virender Sehwag', 'Gautam Gambhir'], 'Srilanka': ['Lasith Malinga', 'Angelo Mathews', 'Kumar Sangakkara'], 'England': ['Alastair Cook', 'Jonathan Trott', 'Kevin Pietersen']}
>>> type(data)
<class 'dict'>
>>> data['President']
'Alan Isaac'

目录遍历

# Ruby
parentDir = 'D:\\MyProject\\Python\\DataStructure\\DataSet2014\\'def find_all_file(filepath)if File.directory?(filepath)Dir.foreach(filepath) do |filename|if filename != "." and filename != ".."find_all_file(filepath + "\\" + filename)endendelseputs filepathend
endfind_all_file parentDir
# Python3
import osparentDir = 'D:\\MyProject\\Python\\DataStructure\\DataSet2014'def find_all_file(parentDir):if os.path.isdir(parentDir): dir_list = os.listdir(parentDir)paths = [os.path.join('%s\\%s' % (parentDir, tt)) for tt in dir_list]for path in paths:find_all_file(path)else:print(parentDir)find_all_file(parentDir)

命令行参数解析

# Ruby
require 'optparse'options = {}
OptionParser.new do |opts|opts.banner = 'here is help messages of the command line tool.'options[:switch] = falseopts.on('-s', '--switch', 'Set options as switch') dooptions[:switch] = trueendopts.on('-n NAME', '--name Name', 'Pass-in single name') do |value|options[:name] = valueendopts.on('-a A,B', '--array A,B', Array, 'List of arguments') do |value|options[:array] = valueend
end.parse!puts options.inspect------------------------------------------------------------
D:\MyProject\Ruby\workspace>ruby test.rb -h
here is help messages of the command line tool.-s, --switch                     Set options as switch-n, --name Name                  Pass-in single name-a, --array A,B                  List of argumentsD:\MyProject\Ruby\workspace>ruby test.rb -s
{:switch=>true}D:\MyProject\Ruby\workspace>ruby test.rb -n Looking
{:switch=>false, :name=>"Looking"}D:\MyProject\Ruby\workspace>ruby test.rb -a Ruby, Python
{:switch=>false, :array=>["Ruby"]}D:\MyProject\Ruby\workspace>ruby test.rb -a Ruby,Python
{:switch=>false, :array=>["Ruby", "Python"]}

Ruby 学习笔记(和 Python3 语法进行对比)相关推荐

  1. python3语法都相同吗_python3.4学习笔记(一) 基本语法 python3不向下兼容,有些语法跟python2.x不一样...

    python3.4学习笔记(一) 基本语法 python3不向下兼容,有些语法跟python2.x不一样,IDLE shell编辑器,快捷键:ALT+p,上一个历史输入内容,ALT+n 下一个历史输入 ...

  2. python基础代码事例-学习笔记:python3,代码。小例子习作(2017)

    http://www.cnblogs.com/qq21270/p/7634025.html 学习笔记:python3,一些基本语句(一些基础语法的代码,被挪到这里了) 日期和时间操作 http://b ...

  3. ruby学习笔记(11)--symbol与hash参数

    symbol是啥就不深入的讨论了,只简单说说symbol的好处 ruby内部对于每个对象,都会有一个数字id用来标识并区分,可以用xxx.object_id来查看 puts "0001&qu ...

  4. python搞笑语句_云计算开发学习笔记:Python3 import语句

    原标题:云计算开发学习笔记:Python3 import语句 想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下: 当解释器遇到 import 语句,如果模块在当前的 ...

  5. python基本语法语句-python学习笔记:基本语法

    原标题:python学习笔记:基本语法 缩进:必须使用4个空格来表示每级缩进,支持Tab字符 if语句,经常与else, elif(相当于else if) 配合使用. for语句,迭代器,依次处理迭代 ...

  6. Ruby学习笔记_索引贴

    学习Ruby也有段时间了,在学习的同时也做了些笔记并发到了园子睐.看到园子里的大虾们在出了一系列文章后都会做个索引贴,这样很方便,所以本人今天抽了个空就把它整理了下,方便自己的同时也方便感兴趣的朋友. ...

  7. java基本语法心得_Java学习笔记(一)——基础语法(上)

    Java学习笔记(一)--基础语法(上) 软件构造 写在前面 编写Java程序时,应注意以下几点:大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的. 类名:对于所有的 ...

  8. Programming Languages PartA Week2学习笔记——SML基本语法

    Programming Languages PartA Week2学习笔记--SML基本语法 首先简单介绍使用的SML语言,参考维基百科和百度百科: ML(Meta Language:元语言)是由爱丁 ...

  9. 《PHP学习笔记——PHP基本语法》

    <PHP学习笔记--PHP基本语法> 前言: PHP是一门服务端脚本语言,像JavaScript一样,也是一门弱类型语言.弱类型语言最大的特点是允许变量隐式转换.这样,相对于Java这种强 ...

  10. 鸟哥的私房菜Linux 学习笔记之 Bash语法

    学习笔记备忘 case的语法 PATH=${PATH}:~/binexport PATHread -p "please input:" wordcase $word in &quo ...

最新文章

  1. Springboot引用外部配置文件
  2. c语言:输入两个正整数m和n,求其最大公约数和最小公倍数
  3. 洛谷 - P3355 骑士共存问题(二分图最大独立集)
  4. Xamarin效果第一篇之时间轴
  5. .jdeveloper_在JDeveloper 12.1.3中为WebSocket使用Java API
  6. 高并发第一弹:准备阶段 了解高并发
  7. linux 以下命令对中正确的是什么,2016年Linux认证模拟真题及答案
  8. 阿里服务器+Centos7.4+Tomcat+JDK部署
  9. UVALive 7455 Linear Ecosystem (高斯消元)
  10. Luhn校验原理与实现【转载】
  11. VIJOS 1512SuperBrother打鼹鼠(二维BIT)
  12. flask html缓存,flask_cache如何缓存动态数据,如何调用缓存数据
  13. 语音识别(ASR)基础介绍第四篇——当今流行做法与CTC-阿里云开发者社区
  14. php标记符 编译,PHP: 编译问题 - Manual
  15. 支持向量机原理及求解 SVM Slater条件 KKT条件 SMO算法 软间隔
  16. 小米音箱蓝牙连不上_小米蓝牙音箱怎样 小米蓝牙音箱如何连接电脑
  17. nvidia 卸载驱动
  18. 51nod - 1378 - 夹克老爷的愤怒
  19. JS——数组中去除空空字符串
  20. android 11.0 12.0添加系统字体并且设置为默认字体

热门文章

  1. 贰零贰壹·伍·壹肆·|VMware|·|壹|·|安装与完善|:关于在windows系统上架设其他虚拟机的准备
  2. Synchronized与Lock的区别(表)
  3. 2021_On Generating Plausible Counterfactual and Semi-Factual Explanations for Deep Learning
  4. 硝烟中的Scrum和XP读书笔记
  5. 现代化薪酬管理体系阶段
  6. TDMA、CDMA(这俩同频原因),提到一点FDMA是什么,理清这些之间的关系
  7. 在地化和本土化的区别_在地化
  8. 拟Linux服务器(中标麒麟)安装DM数据库-静默安装
  9. python围圈报数 青少年编程电子学会python编程等级考试三级真题解析2021年6月
  10. 深度学习读书笔记之RBM(限制波尔兹曼机)