# 斯坦福编程范式 CS107_25

# 使用 Python 重写 RSG

下面的 grammar 有两个 key,分别映射到一个列表上,其中一个是一个长度为 1 的列表,另一个是长度为 3 的列表。

import sys
grammar = {'<struct>':[['This','<object>','is here']],'<object>':[['computer'],['car'],['assiginment']]};

假设上述的内容是一个全局变量。我想要定义这个函数。

choice 是一个 python 内置的随机函数,给入一个整数,它会返回介于 0 和那个整数之间的数字;给一个列表,它从列表中等概率地选择任何地元素。 map 用来进行递归。 seed 的作用是生成一个随机数,如果每一次的第一个随机数是相同的总是 0,那么你运行后得到的第二个随机数也是相同的,会得到同一个序列。

def expand(symbol):
    if symbol.startswith('<'):
        definitions = grammar[symbol]
        expansion = choice(definitions)
        map(expand,expansion)
	else:
        sys.out,write(symbol)
        
seed()
expand('<start>')

# 从内存的角度谈一下对象模型

下述例子中,x 和 y 使用的是同一块内存

> x = [1,2,3]
> x
[1,2,3]
> y = x
> y
[1,2,3]
> x.append(4)
> x 
[1,2,3,4]
> y
[1,2,3,4]

下面的这个例子,w 没有做任何深度拷贝,没有将 z 列表的所有权转移给那个被 w 拥有的列表,从下面的例子中可以看出来,虽然只是浅拷贝,在 python 的数据生命期中都被预留了。

> z = [10,12,14]
> z
[10,12,14]
> w = [z,z]
> w 
[[10,12,14],[10,12,14]]
> z.append(17)
> z
[10,12,14,17]
> w
[[10,12,14,17],[10,12,14,17]]

如果你想要使用复制,那么有两种方法。

有一种模块叫做 copy,可以用来进行复制,生成一个新的内存空间。下面例子中的 z 是进行浅拷贝生成的,它拷贝的深度为 1。

如果想要使用深拷贝,那么可以使用 deep copy

from copy import copy,deepcopy
> x = [14,15,21]
> x
[14,15,21]
> y = x
> y
[14,15,21]
> x is y
True
> z = copy(x)
> z
[14,15,21]
> z = x
False
> m = [1,2,3]
> n = [m,m]
> p = deepcopy(n)

# python 中的对象

python 中的对象和字典差不多而已,在 python 中,没有编译时间元素,不需要预定义类型,直需要将内容添加到字典中。

一个关于类的例子:

class lexicea:
    
    def __init__(self,filename = 'words'):

C++ 中传入对象的地址是在 -1 的参数位置进行传入的,Python 不会那样做,它会很明确地传递有关的容器或对象的地址,包括构造方法,这就是所谓的 self,它不是必须的。self 是是从 objective C 中借来的关键字。因为对象是动态初始化,完全没有编译时元素,它需要这个空的对象。

下面对这个类进行使用:

>>> from lex import lexicea
>>> el = lexicea()		#构建了类 el
>>> lexicea.__dict__	#运行这个会让你看到内部符号其实是以字典的形式进行存放的

# 一些易犯的错误

> o = object()
> o
<---...--->
> o.__dict__
{...
....
.....}
> o.a = 17
> o.b = "hello"
> o.c = False
> o.__dict__
{'a':17,'b':"hello",'c':False}

下面的三行代码和 5~7 行的代码是等效的。

o.a = 17
o.b = "hello"
o.c = False
o.__dict__['a']=17
o.__dict__['b']="helo"
o.__dict__['c']=False

这里所体现出的特点是,支持的对象是可扩展的,收缩的容器。他们必须是以可扩展的方式,那些 C C 和 JAVA 中不需要有的方式,因为 C C JAVA 在任何代码执行之前,已经安排妥当了。Python 是一种完全动态的语言,一切都应该是能扩大和缩小,关于它的一切都应该是动态的,