Python的亲戚们 (之三)
来源:互联网 发布:数据库datetime 格式 编辑:程序博客网 时间:2024/04/28 04:26
http://blog.csdn.net/idisposable
First Eye on Boo Language
在.NET平台上,除了IronPython之外,Python还有另外一个亲戚 - Boo。
但是Boo语言并不真正是Python语言的实现,它只是有着和Python一样的外衣而已。
===========================================================
下面是我读BooPrimer的学习笔记,:)
1. 跟其他的语言教程一样,BooPrimer也是从"hello, world"开始。
print "Hello, World!"
或者
print ("Hello, World")
是不是跟Python中一样?在Python 2.6及以前的print statement采用前一种形式;在Python 3.0之后,print已经成为了一个函数。Boo支持两种形式,我想也是为了和Python兼容吧。
BooPrimer推荐使用宏(print "Hello, World!")的形式,跟Python中的发展方向不一致。下面看看这二者编译之后的代码吧(编译之后用.NET Reflector查看的代码)。
(a) print "hello, world" 编译后的代码是:
Console.WriteLine("hello, world")
(b) print ("hello, world")编译后的代码:
Builtins.print("hello, world")
至于Builtins.print具体做了什么,有兴趣的读者可以自己去看看。
2. String interpolation (字符串插入)
String interpolation让字符串格式化变得很方便。看看例子:
toy = "kitty"
print "hello, ${toy}"
这里能够插入到字符串中的可以是任何合法的Boo表达式。当展开字符串时,Boo会计算该表达式,然后调用表达式结果的ToString方法。可以写几行简单的代码验证这一点。代码如下:
class TestObject:
def ToString():
return "This is an instance of class TestObject"
obj = TestObject()
s = "Result: ${obj}"
3. 在Boo中所有的所有都是对象
这一点不用多解释了,Boo和Python一样 - 在它们的世界里,什么都是对象,内建基础数据类型(如整型,字符,字符串),代码段,解释器都是对象。甚至类型本身也是对象(先前没有接触过Python/Boo的也许会觉得这很疯狂吧)。
>>> obj as object
>>> print obj == null
>>> true
>>>
主要上面的代码中用了as关键字显式地指定了对象的类型。这也是Boo区别与Python的一个地方 - 可以指定对象的类型来增强安全性。而且有一点一定别忘记:Boo并不是真正动态类型的语言,所以对象在其生命周期中类型是固定的。
4. 检测对象的运行时类型(Runtime type of an object)
跟Python不同,Boo因为基于.NET,它的类型系统也是使用.NET的Common Type System (CTS)。
检测对象的方式也和.NET一致。
(a) obj.GetType()
(b) typeof
不过我发现typeof一点都不好用。如下所示:
>>> l = [1, 2, 3]
>>> typeof(l)
Error: The name 'l' does not denote a valid type.
>>> t = l.GetType()
Boo.Lang.List
>>> typeof(t)
Error: The name 't' does not denote a valid type.
>>> typeof(Boo.Lang.List)
>>> Boo.Lang.List
>>>
typeof跟Python中的type()比较起来显得太死板了。
5. 内建函数 (Builtin Functions)
Boo支持一些内建函数如 print, gets, prompt, join, map, array, matrix, iterator,
shellp, shell, shellm, enumerate, range, reversed, zip, cat等。
6. 自定义函数
Boo中自定义函数的语法和Python是一样的。但是对于成员函数的定义和Python有些不同,我将在以后的系列文章中详述。
这里是几个自定义函数的例子:
def Hello():
print "hello"
#这个函数指定了返回值类型
def Hello() as string:
print "hello"
def Hello(name):
print "hello, ${name}"
#这个函数指定了参数的类型
def Hello(name as string):
print "hello, ${name}"
为参数和返回值指定类型使得程序安全性提高了,Boo可以对参数和返回值进行类型检查。
7. Overloading
Boo在函数重载方面做的比Python好很多。来看简单的例子吧。
def Hello():
return "Hello, World!"
def Hello (name as string):
return "Hello, ${name}!"
def Hello(num as int):
return "Hello, Number ${num}!"
def Hello(name as string, other as string):
return "Hello, ${name} and ${other}!"
8. 可变参数
Boo也支持可变参数。e.g.
>>> def Test(*args as (object)):
>>> return args.Length
>>> print Test("hey", "there")
2
>>> print Test(1, 2, 3, 4, 5)
5
>>> print Test("test")
1
>>> a = (7, 9, 8)
>>> print Test(*a)
按照BooPrimer最后一个测试Test(*a)应该返回3。 但是实际使用Boo 0.7.6的结果是出错:
ERROR: The best overload for the method 'Input27Module.test(*(object))' is not compatible with the argument list '(*(int))'.
9. 属性和字段 (property and field)
Boo区别property和field,这对于.NET程序员来说比较舒服。也可以在Boo中通过attribute来定义properties。
class Cat:
[Property(Name)] // 这是一个属性。通过对它的访问来读写字段_name
_name as string // 这是一个字段,不能从类的外部访问,应该使用属性来访问它。
看下边的setter/getter是不是跟C#里边的很象啊?
class Cat:
[Getter(Name)]
_name = 'Meowster'
[Setter(FavoriteFood)]
_favoriteFood as string
fluffy = Cat()
print fluffy.Name
fluffy.FavoriteFood = 'Broccoli'
上边的setter/getter都是隐式的形式,再来看看显式属性的例子。
class Cat:
Name as string:
get:
return _name
set:
_name = value
_name as string
9.1 Pre-condition of property
class Cat:
[Property(Name, Name is not null)]
_name as string
fluffy = Cat()
fluffy.Name = null # 对Name属性设置空值会引发ArgumentException异常
不知道C#中有没有相似的特性?
10. Class modifiers
public, protected, internal, protected internal, private, abstract, final
"public" is assumed if no modifier is specified
Boo向.NET学习定义了一堆的class modifiers, 这样细粒度的访问控制能够满足更好的安全性。
11. interface support
这是Boo相对于Python的一个优点 - 从语言层支持接口的概念。
e.g.
interface IFeline:
def Roar()
Name:
get
set
12.值类型和引用类型
和.NET一样, 所有的类(class)都是引用类型;基础类型为值类型,如int, long, double, bool, byte等。值类型永远都拥有值(不能设置为null),他们有缺省值,例如数值类型的缺省值为0。
13. Class member methods
定义成员方法和Python的语法类似,不同点在于不需要self关键字。
class Cat:
def Roar():
print "Meow!"
cat = Cat()
cat.Roar()
14. 构造函数和析构函数 (Constructor and Destructor)
class Cat:
def constructor():
_name = "Whiskers"
def destructor():
print "${_name} is no more..."
[Getter(Name)]
_name as string
cat = Cat()
print cat.Name
因为.NET的不确定性析构的问题,所以你的代码不能够依赖析构函数被调用。你不知道它什么时候会被调用,也许永远都不会。
15. Method modifiers
abstract: 抽象方法
static: 静态方法
virtual, override - 虚方法和方法重写。
这些都和C#/.NET是一致的。
16. Member visibility
成员的可见性分为几种: public, protected, provate
如果没有显式声明,所有的字段缺省都是protected, 而方法(methods),属性(properties)和事件(events)缺省都是public。
17. 在构造函数中声明属性 (Declaring Properties in the constructor)
这是一个比较好用的语言特性,算是语法糖吧。
class Box:
def constructor():
pass
[Property(Value)]
_value as object
box = Box(Value: 42)
print box.Value
18. 多态和继承
多态和继承是面向对象的两个本质特性。Boo语言中的多态和继承没有什么特别的地方,跟C#语言一样,这样不再赘述。
19. 结构体 (structs)
Boo语言中的结构体完全是从.NET借过来的。结构体是值类型,也可以定义自己的方法。
e.g.
struct Rectangle:
def constructor(w as int, h as int):
_w = w
_h = h
_x as int
_y as int
def Area():
return _w * _h
20. 名字空间 (namespace)
跟Python相比这的确是个好东西 - Python只能借用module来对付名字冲突。
20.1 声明名字空间
在文件头部这样来声明名字空间
namespace MyNamespace
class TypeInTheNamespace():
pass
如果需要导入另外的名字空间呢?也很简单,就想C#一样。
import System
import MyNamespace
import Gtk from "gtk-sharp" // quoted because there is a special character '-'.
21. 枚举 (enumerations)
没有什么特别的地方,看例子吧。
enum Day:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
class Action:
[Property(Day)]
_day as Day
22. 异常 (exceptions)
抛出异常 (raising exceptions)
e.g.
import System
def Execute(i as int):
if i < 10:
raise Exception("Argument must be greater or equal to 10.")
print i
捕获异常 (catching exceptions)
捕获异常有三种形式:try-except, try-ensure, 和try-except-ensure
看看下边的例子。
# try-except example
import System
try:
print 1 / 0
except e as DivideByZeroException:
print "oops"
print "Doing other stuff"
# try-ensure example
import System
try:
s = MyClass
s.DoSomethingBad()
ensure:
print "This code will be executed, whether there is an error or not."
这里的ensure跟C#的finally是等同的东西。
try-except-ensure是上边两种形式的结合。
# try-except-ensure example
import System
try:
s = MyClass
s.DoSomethingBad()
except e as Exception:
print "Problem! ${e.Message}"
ensure:
print "This code will be executed, whether there is an error or not."
23. 函数调用和多线程 (functions as objects and multithreading)
在Boo中,一切都是对象,所以函数也不例外。每个函数都有三个方法:
Invoke: 跟正常调用函数一样
BeginInvoke: 启动一个工作线程来运行这个函数
EndInvoke: 等待先前启动的线程完成函数调用并返回计算结果。
因为Boo提供便利的异步函数调用,多线程编程变得很容易。
24. generators (生成器或生成子,怎么翻译都觉得难听)
用过Python的读者对generator一定不陌生。
generator 表达式的语法定义:
<expression> for <declarations> [as <type>] in <iterator> [if|unless <condition>]
e.g.
>>> List(x for x in range(5)) // 最简单的形式
[0, 1, 2, 3, 4]
>>> List(x for x in range(5) if x % 2 == 0)
[0, 2, 4]
generator 方法:
gemerator方法使用yield关键字,这样的方法看起来象普通的方法但是能够给调用者多次返回。
是不是难明白,看看例子就知道了。
def TestGenerator():
i = 1
yield i
for x in range(10):
i *= 2
yield i
print List(TestGenerator())
generator是继承自IEnumerable,所以可以和for ... in 一起使用。
25. 宏 (macros)
Boo提供了几种宏让编程更便利。不过我有一个疑问:不知道Boo是否支持用户自定义的宏?
print Macro
这个我们已经熟悉了。 e.g.
print "Hello there"
print "Hello", "there"
print "first", "second", "third", "more", "more and more"
assert macro
这个是防御性编程的宝贝。
assert true // 总是会通过
assert false, "message" // 总是会失败
using macro
跟C# 中的using 用法一样,为受保护对象提供了一个生命周期控制。
e.g.
using w = StreamWriter("test.txt"):
w.WriteLine("Hello there!")
lock macro
和C#一样,lock macro用来在多线程环境下同步对象的访问。
e.g.
lock database:
database.Execute("UPDATE messages SET id = id + 1")
debug macro
和print Macro类似,不同点在于print输出到System.Console, 而debug macro输出到System.Diagnostics.Debug。
26. Duck typing
也许不翻译是最容易理解的了,:)
definition: duck typing is a humorous way of describing the type non-checking system. initially coined by Dave Thomas in the Ruby community, its premise is that (referring to a value) "if it walks like a duck, and talks like a duck, then it is a duck."
Even though Boo is a statically typed language, Duck Typing is a way to fake being a dynamic language. Duck typing allows variables to be recognized at runtime, instead of compile time. Though this can add a sense of simplicity, it does remove a large security barrier.
e.g.
d as duck
d = 5 // 现在d是一个整型
print d
d += 100 // 能够做任何整型允许的操作
d = "hello" // 闲杂d变成了字符串类型了
print d
d = d.ToUpper() // 可以执行任何字符串操作了
print d
================================================================================================================
Boo的学习笔记就到这里为止了。以后对它的了解多了再来写吧。
相关连接:
1. Boo http://boo.codehaus.org/ Boo的官方网站
2. SharpDevelop http://www.icsharpcode.net/OpenSource/SD/ 提供了一个Boo的IDE环境
3. IronPython的介绍 http://blog.csdn.net/IDisposable/archive/2008/10/08/3035790.aspx
- Python的亲戚们 (之三)
- Python的亲戚们 (之二)
- Python的亲戚们 (之一)
- 亲戚
- 亲戚
- 亲戚
- 亲戚
- 亲戚
- 亲戚
- 亲戚
- java制作的亲戚计算器(三姑六婆计算器)
- 并查集(亲戚)
- 并查集(亲戚)
- 亲戚(图论算法)
- 亲戚(附分析图)
- Python之旅(三)
- Python编程(三):Python之MVC
- Python基础学习教程(三)之字符串的秘籍
- ◆Delphi多线程编程之三 同步读写全局数据 ◆(乌龙哈里2008-10-12)
- 啊里巴巴的盈利模式是怎样的
- 生成GUID的方法
- ubuntu安装手记
- 事件
- Python的亲戚们 (之三)
- Hadoop 安装部署-多服务器
- php学习资料
- ubuntu安装软件
- 利用BrandZ在Solaris上运行Linux应用程序
- HoneyBot构造入侵检测系统
- Asp.net 不允许循环文件引用
- MYSQL因为区分大小写而引起找不到表
- 修改google桌面索引文件的存放位置