设为首页 收藏本站
查看: 567|回复: 0

[经验分享] python 与 ruby 之间的区别

[复制链接]

尚未签到

发表于 2017-5-1 09:54:16 | 显示全部楼层 |阅读模式
Number 类型
python 是 int 和 long
ruby 是 Fixnum 和 Bignum

num = 8
7.times do
print num.type, " ", num, "\n"
num *= num
end
produces: Fixnum 8
Fixnum 64
Fixnum 4096
Fixnum 16777216
Bignum 281474976710656
Bignum 79228162514264337593543950336
Bignum 6277101735386680763835789423207666416102355444464034512896

对象区别

isinstance(object, classinfo) #是否为类或继承类的实例
class A(object):
...     pass
... class B(A):
...     pass
>>> b = B()
>>> isinstance(b,B)
59: True
>>> isinstance(b,A)
60: True



instance_of?(object, classinfo) #是否为该类
kind_of?(object, classinfo) # #是否为类或继承类的实例


String 类型
1. 类型

>>> type("s")
20: <type 'str'>
>>> type(u"s")
21: <type 'unicode'>



irb(main):236:0> "dd".type
=> String


2.字符串格式化

>>> print '%s %s' % ("hi","world")
>>> print '%(name)s %(v)s' % {"name":1 ,"v":2}



>>> a= "world"
>>> puts "hello \t #{a}"


3. print函数

>>> print "hi world" #换行
>>>  print "hi world", #不换行



>>> puts "hi world" #换行
>>>  print "hi world"  #不换行


4.多行字符串

astring = """
The body of the string
is the input lines up to
one ending with the same
text that followed the '<<'
"""



aString = <<END_OF_STRING
The body of the string
is the input lines up to
one ending with the same
text that followed the '<<'
END_OF_STRING


字符串拼接,这个比较重要要提一下join方法

",".join([1,2,3])



[1,2,3].join(",")


5.ruby的其他表现形式

>>> %q {hi world} #single-quoted string
>>>  %Q {hi world} #double-quoted string



Range 类型
在这里ruby 使用 a.to_enum (Included Modules Enumerable)的方法对序列进行迭代,而python的range 直接生成一个数组,python的xrange的实现与 ruby的Enumerable类似

>>> range(10)
>>> xrange(10)



>>> (0..9).to_a
>>> 0..9


Regular Expressions
ruby 里的正则表达式似乎没有global 参数
IGNORECASE: INT2FIX(RE_OPTION_IGNORECASE)
EXTENDED:   INT2FIX(RE_OPTION_EXTENDED)
MULTILINE:  INT2FIX(RE_OPTION_MULTILINE)

>>> a = "Fats Waller"  
>>> a =~ /a/  #这里返回匹配位置


python 也没有global 但是有 DOTALL 并且支持re.UNICODE

>>> d = re.match(r"(.+)+","abc\nccc",re.DOTALL)
>>> d.groups()
42: ('abc\nccc',)



>>> re.subn(r"(hello)","\g<1> edisonlz's","hello world")
51: ("hello edisonlz's world", 1)



irb(main):020:0> "edison:lz".gsub(/(\w+):(\w+)/,'\2,\1')
=> "lz,edison"



>>> type(r"dd")
52: <type 'str'>



irb(main):021:0> /dd/.type
=> Regexp


对Class 的扩展
python 使用metaclass对类进行扩展(初始化类的类),而ruby 使用 partial class和 mixin 对类进行扩展,python 不支持 partial class  和 mixin的方法,


class ModelBase(type):
"""Metaclass of the Model."""
def __new__(cls, name, bases, dct):
return type.__new__(cls, name, bases, dct)
def __init__(cls, name, bases, attrs):
"""
intialize name base modle  attribute
param:
name:string
bases:base model
attrs: attribute
"""
super(ModelBase, cls).__init__(name, bases, attrs)
cls._initialize_attributes(cls, name, bases, attrs)
cls._initialize_manager(cls)
def _initialize_attributes(self,model_class, name, bases, attrs):
"""
Initialize the attributes of the model.
param:
model_class:object
name:string
bases:base model
attrs:attribute
"""
#主要功能:添加属性列表
model_class.attributes = {}
for k, v in attrs.iteritems():
if isinstance(v,Attribute):
model_class.attributes[k] = v
v.name = v.name or k

def _initialize_manager(self,model_class):
"""
Initializes the objects manager attribute of the model.
param:
model_class:object
"""
model_class.objects = ModelSet(model_class)
pass

class Model(object):
__metaclass__ = ModelBase



class Array  
def inject(n)  
each { |value| n = yield(n, value) }  
n  
end  
def sum  
inject(0) { |n, value| n + value }  
end  
def product  
inject(1) { |n, value| n * value }  
end  
end  
[ 1, 2, 3, 4, 5 ].sum  » 15  
[ 1, 2, 3, 4, 5 ].product  » 120  

decorator的应用
python 使用func decorator 的方法,ruby 使用 yield block的方法和Rails alias_method的方法

>>> _cache = {}
... def cache(sec=10):
...     def wrap(f):
...         def func(*args,**kwargs):
...             data = _cache.get(",".join(args))
...             if not data:
...                 data = f(*args,**kwargs)
...                 _cache[",".join(args)] = data
...                 print "no cache"
...             else:
...                 print "in cache"
...             return data
...         return func
...     return wrap
...
... @cache(10)
... def page(html):
...     return "response %s" % html
>>> page("haha")
no cache
70: 'response haha'
>>> page("haha")
in cache
71: 'response haha'


class Object
def memory(name)
ori = "ori_#{name}"
alias_method ori,name
define_method(name) do
cache = instance_variable_get("@#{name}")
if cache
return cache
else
cache =  send(ori)
instance_variable_set("@#{name}",cache)
return cache
end
end
end
end
class A
def run
puts "sleeping"      
sleep 5
"a"
end
memory(:run)
end  
a = A.new
puts a.run
puts a.run



def select(n)
t = []
for i in n
t.push(i) if yield(i)
end
return t
end
=> nil
irb(main):052:0> select([1,2,3]){|i| i>2}
=> [3]



module ActiveRecordExtension
def self.included(base)
base.extend(ClassMethods)
base.class_eval do
class << self
p "Aliasing find" # Used to check if alias_method isn't
called twice
alias_method :find_without_someting, :find
alias_method :find, :find_with_someting
end
end
end
module ClassMethods # :nodoc:
def find_with_something(*args)
p "0"
x = find_without_something(*args)
p "1"
return x
end
end   
end

ruby还有一个写滴向javascript滴东东

irb(main):015:0> c = "1"
irb(main):015:0> class << c
irb(main):016:1>   def to_ff
irb(main):017:2>     self.to_f
irb(main):018:2>     end
irb(main):019:1>   end
=> nil
irb(main):020:0> c.to_ff
1.0


lambda的应用
python和ruby 中都有有lambda,并且意思也都一样,但是python 中没有 proc
ruby 中的 lambda  和 proc 是一个东东
proc   { |...| block }  => a_proc
lambda { |...| block }  => a_proc
---------------------------------------------------------------------------------
Equivalent to Proc.new, except the resulting Proc objects check the number of parameters passed when called.


>>> def f(x):
...     return x*2
...     
>>> f(3)
>>> g = lambda x: x*2  
>>> g(3)



>>> g = lambda { |x| x*2  }
>>> g.call(3)


一般情况lambda 表达式与闭包一起应用

def nTimes(aThing)  
return proc { |n| aThing * n }  
end  
p1 = nTimes(23)  
p1.call(3)  » 69  
p1.call(4)  » 92  
p2 = nTimes("Hello ")  
p2.call(3)  » "Hello Hello Hello "  


python 中滴闭包,这里举个小列子,用于一次完成多个替换

>>> import re
... def mre(dic,text):
...     rc = re.compile("|".join( map( re.escape,dic.keys() ) ) )
...     print rc
...     def get_value(match):
...         return dic.get(match.group(0))
...     return rc.sub(get_value,text)
>>> dic = {"a":"A","b":"B"}
... mre(dic,"abab")
<_sre.SRE_Pattern object at 0x01A8CED0>
115: 'ABAB'


yield  区别
在python 中yield 是一个generator 可以保存住当前的context,这一点和ruby 类似,
但是ruby的yield 是调用一个block 也就是调用一个 proc.new {}
我个人编程不习惯使用python的yield

>>> def y(n):
...     for  i in xrange(n):
...         yield i
... for g in y(10):
...     print g ,
0 1 2 3 4 5 6 7 8 9



def any(n)
t = []
for i in n
return true if yield(i)
end
return false
end
=> nil
irb(main):052:0> any([0,1,0]){|i|  i!=0}
=>  true


symbol and tuple
在python 中建议在传递参数和迭代的时候使用tuple来减少开销
在ruby中大家使用 symbol 来提高访问速度,都是挺好的特性

:edisonlz.id
('edison','lz')


inheritance
python 中支持多继承,ruby 不支持多继承但是支持mixin
python 多继承的查找链规则: This is depth-first, left-to-right
ruby 中的查找链规则:self->mixin->super

class Base():
pass
class Car():
pass
class BMW(Base,Car):
pass


ruby中的继承:
in the diagram below, "normal" classes are green, and meta-classes are blue. The dashed lines represent "instance off" (the "klass" pointer), and the solid lines represent "inherits" (the "super" method):
DSC0000.png
block

The blocks used by iterators (such as loop and each) are a little different. Normally, the local variables created in these blocks are not accessible outside the block.
[ 1, 2, 3 ].each do |x|
y = x + 1
end
[ x, y ]

produces: prog.rb:4: undefined local variable or method `x'for #<Object:0x401c0ce0> (NameError)


ruby独有的特性

What happens when you copy a frozen object? That depends on the method you use. If you call an object's clone method, the entire object state (including whether it is frozen) is copied to the new object. On the other hand, dup typically copies only the object's contents---the new copy will not inherit the frozen status.
str1 = "hello"  
str1.freeze  » "hello"  
str1.frozen?  » true  
str2 = str1.clone  
str2.frozen?  » true  
str3 = str1.dup  
str3.frozen?  » false  


private protected,和public
python 中是没有private protected,和public滴
ruby中对private protected,和public是有定义滴,并且能对定义重载

>>> class Base(object):
...     def __p(self):
...         print "private"
...     def _prot(self):
...         print "protected"
...     def p(self):
...         print "public"
>>> b = Base()
>>> b.__p()
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
b.__p()
AttributeError: 'Base' object has no attribute '__p'
>>> b._prot()
protected
>>> b.p()
public
>>> b._Base__p
0: <bound method Base.__p of <__main__.Base object at 0x01985C70>>
>>> b._Base__p()
private


class Base
def aMethod
puts "Got here"
end
private :aMethod
end
class Derived1 < Base
public :aMethod
end
class Derived2 < Base
end



DSC0001.png
令人困惑地instance_eval and class_eval

Use ClassName.instance_eval to define class methods.
Use ClassName.class_eval to define instance methods.
That’s right. Not a typo. Here are some examples, shamelessly stolen from his post:
1
# Defining a class method with instance_eval
2
Fixnum.instance_eval { def ten; 10; end }
3
Fixnum.ten #=> 10
4
5
# Defining an instance method with class_eval
6
Fixnum.class_eval { def number; self; end }
7
7.number #=> 7


method_missing
ruby 中独有滴methods missing 使得rails更加滴方便
user.find_by_XXX
uesr.find_or_create_by_xxx
当然这些都不神秘,
def method_missing(method_id, *arguments, &block)
if match = DynamicFinderMatch.match(method_id)
attribute_names = match.attribute_names
super unless all_attributes_exists?(attribute_names)
if match.finder?
class DynamicFinderMatch
def self.match(method)
df_match = self.new(method)
df_match.finder ? df_match : nil
end
def initialize(method)
@finder = :first
case method.to_s
when /^find_(all_by|last_by|by)_([_a-zA-Z]\w*)$/
@finder = :last if $1 == 'last_by'
@finder = :all if $1 == 'all_by'
names = $2
when /^find_by_([_a-zA-Z]\w*)\!$/
@bang = true
names = $1
when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
@instantiator = $1 == 'initialize' ? :new : :create
names = $2
else
@finder = nil
end
@attribute_names = names && names.split('_and_')
end
attr_reader :finder, :attribute_names, :instantiator
def finder?
!@finder.nil? && @instantiator.nil?
end
def instantiator?
@finder == :first && !@instantiator.nil?
end
def bang?
@bang
end
end

const_missing 也不神秘

class Module
define_method(:const_missing) do |name|
name.to_s
end
A =》 'A'


查找路径

python sys.path
ruby $:
rails $LOAD_PATH
$: == $LOAD_PATH


django 和rails之间的区别
框架:两种框架都是MVC,
REST: django 对REST 支持的并不好, 不像Rails那面优雅
模板系统:django的模板系统那就是个X,实在受不了,读取模板文件要几百毫秒,但幸运滴是,有jinja2模板系统,使用c写滴,这个很让人满意,rails虽然也有第三方的模板系统但是,与rails版本有关联,这个不大好
Model : django 使用 objects.filter和objects.get 功能比较少,而且查询关键字比较怪
               rails 使用 find,并且支持 select ,where 等字段重写,挺好滴
DB :目前 django 还不支持db connection poll,需要第三方滴
         rails 目前支持 db connection poll
但是除了django 和 rails 相比,python 在其他领域那就比ruby强太多了,
例如:wxpython,tornado,twisted,pypy, cjson, pylibmc,都是被人津津乐道的,ruby 似乎只有rails可以被人津津乐道,杯具啊!

加载环境 rails 和 django 使用的加载环境方法基本一样
  rails 加载顺序
  
require File.join(File.dirname(__FILE__), 'boot')
# All that for this:
Rails.boot!
def boot!
unless booted?
preinitialize
pick_boot.run
end
end
def preinitialize
load(preinitializer_path) if File.exist?(preinitializer_path)
end
def pick_boot
(vendor_rails? ? VendorBoot : GemBoot).new
end
class Boot
def run
load_initializer
Rails::Initializer.run(:set_load_path)
end
end
class GemBoot < Boot
def load_initializer
self.class.load_rubygems
load_rails_gem
require 'initializer'
end
end
#   Rails::Initializer.run do |config|
#     config.frameworks -= [ :action_mailer ]
#   end
class Initializer
def self.run(command = :process, configuration = Configuration.new)
yield configuration if block_given?
initializer = new configuration
initializer.send(command)
initializer
end

def process
Rails.configuration = configuration
check_ruby_version
install_gem_spec_stubs
set_load_path
add_gem_load_paths
require_frameworks
set_autoload_paths
add_plugin_load_paths
load_environment
preload_frameworks
initialize_encoding
initialize_database
initialize_cache
initialize_framework_caches
initialize_logger
initialize_framework_logging
initialize_dependency_mechanism
initialize_whiny_nils
initialize_time_zone
initialize_i18n
initialize_framework_settings
initialize_framework_views
initialize_metal
add_support_load_paths
check_for_unbuilt_gems
load_gems
load_plugins
# pick up any gems that plugins depend on
add_gem_load_paths
load_gems
check_gem_dependencies
# bail out if gems are missing - note that check_gem_dependencies will have
# already called abort() unless $gems_rake_task is set
return unless gems_dependencies_loaded
load_application_initializers
# the framework is now fully initialized
after_initialize
# Setup database middleware after initializers have run
initialize_database_middleware
# Prepare dispatcher callbacks and run 'prepare' callbacks
prepare_dispatcher
# Routing must be initialized after plugins to allow the former to extend the routes
initialize_routing
# Observers are loaded after plugins in case Observers or observed models are modified by plugins.
load_observers
# Load view path cache
load_view_paths
# Load application classes
load_application_classes
# Disable dependency loading during request cycle
disable_dependency_loading
# Flag initialized
Rails.initialized = true
end

def default_load_paths
paths = []
# Add the old mock paths only if the directories exists
paths.concat(Dir["#{root_path}/test/mocks/#{environment}"]) if File.exists?("#{root_path}/test/mocks/#{environment}")
# Add the app's controller directory
paths.concat(Dir["#{root_path}/app/controllers/"])
# Followed by the standard includes.
paths.concat %w(
app
app/metal
app/models
app/controllers
app/helpers
app/services
lib
vendor
).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
paths.concat builtin_directories
end
return to environment.rb
proceed......


在谈一下rack 和 tornado
tornado是一个lightweight web server
可是rack  比tornado还要 lightweight ,因为tornado 实现了自己的网络层
,rack则使用fastcgi,cgi,mongrel这些现有滴实现
还有ruby 滴sinatra 是rack 滴扩展,但是提倡 minimalist,更少地代码。

对ruby滴扩展


class NilClass
def try(*args)
nil
end
end
=> nil
user = User.find(100)
user ? user.name : nil
user.try(:name)


class Object
def blank?
return  respond_to?(:empty) ? empty? : !self
end
def present?
!blank?
end
end
=> nil
a = ""
=> ""
a.present?
=> false
a.blank?
=> true


ruby metaprogramming


yes = "yes"
ok = "ok"
String.class_eval do
define_method(yes) do
print ok
end
end
puts "123".yes #=> ok
#create singleton methods
#String.class_eval do
# class << self
#         define_method(yes) do
#           print ok
#         end
# end
#end
#puts String.yes
#C:/Users/liuzheng/Desktop/a.rb:46:in `singletonclass': undefined local variable
#or method `yes' for #<Class:String> (NameError)
#        from C:/Users/liuzheng/Desktop/a.rb:45:in `block in <main>'
#        from C:/Users/liuzheng/Desktop/a.rb:44:in `class_eval'
#        from C:/Users/liuzheng/Desktop/a.rb:44:in `<main>'
#because class << self has new scope
yes = "yes"
ok = "ok"
metaclass = (class <<String; self;end)
metaclass.class_eval do
define_method(yes) do  
puts ok
end
end
puts String.yes => "ok"
DSC0002.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-371510-1-1.html 上篇帖子: python 快捷函数使用 下篇帖子: 使用python统计单词出现的个数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表