我是先接触 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
解压一个安装包,进入解压文件夹。
[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 命令安装,但是安装的可能不是最新的:
依赖包的话就使用 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)>
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 了
# test.rb
puts <<~EOF
this is the first line
this is the second line
EOF
[root@master ruby_learning]# ruby test.rb
this is the first line
this is the second line
------------------------------------------------------
# test.rb
puts <<-EOF
this is the first line
this is the second line
EOF
[root@master ruby_learning]# ruby test.rb
this is the first line
this is the second line
# lambda 函数参数检查更为严格
[1] pry(main)> prc1 = Proc.new do |a, b, c|
[1] pry(main)* puts [a, b, c].inspect
[1] pry(main)* end
=> #
[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
=> #
[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)
=> #
[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)
=> #
[10] pry(main)> cube.call(5)
LocalJumpError: unexpected return
from (pry):18:in `block in power_of'
[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
边界符号可以用如下其他符号替换
|...|, #...#, !...!, +...+, (...), [...], <...>, /.../
# 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 "", line 1
print "Hello World"
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("Hello World")?
>>>
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)>
更严谨的说,Ruby 的方法也是尽可能不用 return,除非迫不得已(比如要提前返回一些东西)。有点像用括号一样,一般默认返回方法里边最后一个表达式的值。
# Ruby
def return_test
"hello world"
"I am Looking"
end
return_result = return_test
puts return_result
D:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
I am Looking
Process finished with exit code 0
--------------------------------------------------------------------------------
def return_test
return "hello world"
"I am Looking"
end
return_result = return_test
puts return_result
D:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
hello world
Process 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
None
Process 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 world
Process 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.
=end
puts "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 "", line 1, in
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)
>>> type(False)
>>> type(None)
>>> 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定义。
# 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")
=> true
irb(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
=> :foo
irb(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
>>> address.values()
dict_values(['Looking', 'lukaiyi', '405902'])
>>> address.values
>>> 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"
=> 2
irb(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
变量在使用之前都需要先赋值,这应该是它们的相同点了。
# Ruby
sub.rb
$x = 1 #对全局变量赋值
x = 1 #对本地量赋值
test.rb
$x = 0
x = 0
require './sub'
p $x
p x
D:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
1
0
Process finished with exit code 0
------------------------------------------------------------
irb(main):037:0> x + 1
NameError: undefined local variable or method `x' for main:Object
from (irb):37
from /usr/bin/irb:12:in `'
# 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 `'
------------------------------------------------------------
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 "", line 1, in
NameError: name 'x' is not defined
------------------------------------------------------------
# Python3一般也使用全大写来表示常量,但是你要改的话就该,反正不关我们Python的事儿,我就当你知道你在做什么就是了。
>>> TEST = 1
>>> TEST = 2
------------------------------------------------------------
>>> if = 1
File "", line 1
if = 1
^
SyntaxError: invalid syntax
------------------------------------------------------------
>>> a, b, c = 1, 2, 3
>>> a, b, c = 1, 2, 3, 4
Traceback (most recent call last):
File "", line 1, in
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']
对不起,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.
# 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 HelloWorld
def instance_method
puts "instance method"
end
end
class HelloWorld
def test
puts "test"
end
end
HelloWorld.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 = age
end
# set 方法
def name=(name)
@name = name
end
# get 方法
def name
@name
end
# attr_accessor相当于attr_reader和attr_writer的合集,实际上是在定义类成员变量的时候就给他定义了一个get和set方法。
attr_accessor :age
# 在ruby中,类成员变量都是私有的,不能直接通过(类名.成员变量名)这样来对成员变量值进行操作。
# get/set 方法也可以像下面这么单独创建,如果没有创建的话,不能按照如下这样使用:
# 实例对象.age
# 实例对象.age = 2
attr_reader :age # get
attr_writer :age # set
def say_something(msg) # 实例方法
puts msg
end
# 类方法通过 self 与实例方法进行区分,只能通过类进行调用
def self.say(msg)
puts msg
end
# 可以通过类方法或者实例方法修改类变量
# 实例方法
def modify_species(new_species)
@@species = new_species
end
def species
@@species
end
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 = name
self._age = age
# An instance method. All methods take "self" as the first argument
def say(self, msg):
print("{name}: {message}".format(name=self.name, message=msg))
# Another instance method
def 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
@classmethod
def get_species(cls):
return cls.species
# A static method is called without a class or instance reference
@staticmethod
def 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 # getter
def age(self):
return self._age
# This allows the property to be set
@age.setter
def age(self, age):
self._age = age
# This allows the property to be deleted
@age.deleter
def 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 = name
self.age = age
# 实例方法,第一个参数需要是self,它表示一个具体的实例对象本身,因为方法可能用的实例本身的一些变量
def instance_method(self):
print(f"Hello, I am instance_method, my name is {self.name}")
# 如果用staticmethod装饰,那么就可以无视这个self,而将这个方法当成一个普通的函数使用
@staticmethod
def static_method():
print("Hello, I am static_method")
return "Hello, I am static_method"
# 如果用classmethod,它的第一个参数是cls,它表示这个类本身,可以通过类名进行调用
# 可在类方法中使用静态方法
@classmethod
def 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_method
Process finished with exit code 0
# Ruby
# 基类
class Human
@@foo = 0
# 下面这两个函数类似于类变量的 get/set 方法
def self.foo
@@foo
end
def self.foo=(value)
@@foo = value
end
end
# 派生类(子类)
class Worker < Human
end
puts Human.foo #=> 0
puts Worker.foo #=> 0
# 类变量被它的所有子类共享
puts Human.foo = 2
puts Worker.foo #=> 2
--------------------------------------------------------------------------------
class Human
@bar = 0
def self.bar
@bar
end
def self.bar=(value)
@bar = value
end
end
class Doctor < Human
end
# 类实例变量不被子类所共享
Human.bar #=> 0
Doctor.bar #=> nil
# Python3
class Human:
# 类属性,被类的所有实例共享
species = "H. sapiens"
def __init__(self, name, age=0):
self.name = name
self._age = age
# An instance method. All methods take "self" as the first argument
def say(self, msg):
print("{name}: {message}".format(name=self.name, message=msg))
# Another instance method
def 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
@classmethod
def get_species(cls):
return cls.species
# A static method is called without a class or instance reference
@staticmethod
def 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 # getter
def age(self):
return self._age
# This allows the property to be set
@age.setter
def age(self, age):
self._age = age
# This allows the property to be deleted
@age.deleter
def age(self):
del self._age
class Superhero(Human):
species = 'Superhuman'
def __init__(self, name, movie=False,
superpowers=["super strength", "bulletproofing"]):
# add additional class attributes:
self.fictional = True
self.movie = movie
# be aware of mutable default values, since defaults are shared
self.superpowers = superpowers
super().__init__(name) # 调用父类的初始化函数
# override the sing method
def sing(self):
return 'Dun, dun, DUN!'
# add an additional instance method
def 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 checks
if isinstance(sup, Human):
print('I am human') # 超级英雄也是人,所以实例化的对象仍然是父类的一个实例
if type(sup) is Superhero:
print('I am a superhero')
# 子类会优先去自己类本身找相应的方法和属性,找不到才到父类继续寻找
print(sup.get_species()) # => Superhuman
# Calls overridden method
print(sup.sing()) # => Dun, dun, DUN!
# Calls method from Human
sup.say('Spoon') # => Tick: Spoon
# Call method that exists only in Superhero
sup.boast() # => I wield the power of super strength!
# => I wield the power of bulletproofing!
# Inherited class attribute
sup.age = 31
print(sup.age) # => 31
# Attribute that only exists within Superhero
print('Am I Oscar eligible? ' + str(sup.movie))
简单理解你就把他当成一个 namespace (命名空间),这样在调用的时候不至于太混乱。
# Ruby
# trig.rb
module Trig
PI = 3.141592654
def Trig.sin(x)
Math.sin(x)
end
def Trig.cos(x)
Math.cos(x)
end
end
--------------------------------------------------------------------------------
# moral.rb
module Moral
VERY_BAD = 0
BAD = 1
def 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, wrongdoing
D:\Ruby23-x64\bin\ruby.exe D:/MyProject/Ruby/workspace/test.rb
0.7071067812590626
0.0
Process finished with exit code 0
--------------------------------------------------------------------------------
# Ruby
module ModuleExample
def foo
'foo'
end
end
# include modules 将他们的方法和类实例进行绑定(也即只能通过生成的实例来进行调用)
# extend modules 将他们的方法和类本身进行绑定 (也即只能通过类本身进行调用)
class Person
include ModuleExample
end
class Book
extend ModuleExample
end
puts 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 ConcernExample
def self.included(base)
base.extend(ClassMethods)
base.send(:include, InstanceMethods)
end
module ClassMethods
def bar
'bar'
end
end
module InstanceMethods
def qux
'qux'
end
end
end
class Something
include ConcernExample
end
puts Something.bar #=> "bar"
puts Something.qux #=> NoMethodError: undefined method `qux'
puts Something.new.bar #=> NoMethodError: undefined method `bar'
puts Something.new.qux #=> "qux"
新建 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)
>>> 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)
end
end
else
puts filepath
end
end
find_all_file parentDir
# Python3
import os
parentDir = '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] = false
opts.on('-s', '--switch', 'Set options as switch') do
options[:switch] = true
end
opts.on('-n NAME', '--name Name', 'Pass-in single name') do |value|
options[:name] = value
end
opts.on('-a A,B', '--array A,B', Array, 'List of arguments') do |value|
options[:array] = value
end
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 arguments
D:\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"]}