上篇备忘主要是面向过程来讲述的,其实python是凡事都是对象的一种解释语言。包括类型int啊等等都是对象,与C/C++显然不同,在这两个语言中,类型是作为原子来定义的,主要是用来分配内存字节而用,没有所谓方法,当然这点在VC中做了一定改变,比如对字符串的处理显然是比C要方便一些。
python和perl,还是Python容易懂些,效率差了
2,面向对象的python3.1,self参数
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候你不为这个参数赋值,Python会提供这个值。这个特别的变量指对象本身,按照惯例它的名称是self。
self 本身不需要赋值,由python自动完成功能,如果你的实例调用一个方法,例如:假如你有一个类称为MyClass和这个类的一个实例MyObject。当你调用这个对象的方法MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method(MyObject, arg1, arg2)#!/usr/bin/python # Filename: simplestclass.py class Person: pass # An empty block p = Person() print p如果你去掉pass前面的缩进,会提示错误,期待一个缩进,一定要记住python是由缩进来区别语句块的,习惯C的人要留心。
#!/usr/bin/python # Filename: method.py class Person: def sayHi(self): print 'Hello, how are you?' p = Person() p.sayHi()# This short example can also be written as Person().sayHi()
#!/usr/bin/python # Filename: class_init.py class Person: def __init__(self, name): self.name = name def sayHi(self): print 'Hello, my name is', self.name p = Person('Swaroop') p.sayHi() # This short example can also be written as Person('Swaroop').sayHi()这里面的属性域没有声明啊,也不说什么类型,在语法严格C++中显的是相当糟糕。
创建一个类的新实例的时候,把参数包括在圆括号内跟在类名后面,从而传递给__init__方法。
这个你要是习惯C++/Java之类的强制类型申明语言,看到这个self.name很不适应。还是把self参数当成系统需要的参数就好了。
#!/usr/bin/python # Filename: objvar.py class Person: '''Represents a person.''' population = 0 def __init__(self, name): '''Initializes the person's data.''' self.name = name print '(Initializing %s)' % self.name # When this person is created, he/she # adds to the population Person.population += 1 def __del__(self): '''I am dying.''' print '%s says bye.' % self.name Person.population -= 1 if Person.population == 0: print 'I am the last one.' else: print 'There are still %d people left.' % Person.population def sayHi(self): '''Greeting by the person. Really, that's all it does.''' print 'Hi, my name is %s.' % self.name def howMany(self): '''Prints the current population.''' if Person.population == 1: print 'I am the only person here.' else: print 'We have %d persons here.' % Person.population swaroop = Person('Swaroop') swaroop.sayHi() swaroop.howMany() kalam = Person('Abdul Kalam') kalam.sayHi() kalam.howMany() swaroop.sayHi() swaroop.howMany()观察可以发现__init__方法用一个名字来初始化Person实例。在这个方法中,我们让population增加1,这是因为我们增加了一个人。同样可以发现,self.name的值根据每个对象指定,这表明了它作为对象的变量的本质。
运行上述脚本,提示Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0xb7746eec>> ignored;
原因是对象销毁时,全局变量的问题。
我另写了一篇备注,记录学习一下错误和心得,这里先列出遇到的问题。记住一点,不要使用__def__方法。
当对象不再被使用时,__del__方法运行,但是很难保证这个方法究竟在 什么时候 运行。
我们正常运行一次:
我们在这个脚本里面添加:
3.5,继承
面向对象的核心概念之一,为了代码重用和逻辑相关性而定义。有过OOP基础的都应该不陌生。#!/usr/bin/python # Filename: inherit.py class SchoolMember: '''Represents any school member.''' def __init__(self, name, age): self.name = name self.age = age print '(Initialized SchoolMember: %s)' % self.name def tell(self): '''Tell my details.''' print 'Name:"%s" Age:"%s"' % (self.name, self.age), class Teacher(SchoolMember): '''Represents a teacher.''' def __init__(self, name, age, salary): SchoolMember.__init__(self, name, age) self.salary = salary print '(Initialized Teacher: %s)' % self.name def tell(self): SchoolMember.tell(self) print 'Salary: "%d"' % self.salary class Student(SchoolMember): '''Represents a student.''' def __init__(self, name, age, marks): SchoolMember.__init__(self, name, age) self.marks = marks print '(Initialized Student: %s)' % self.name def tell(self): SchoolMember.tell(self) print 'Marks: "%d"' % self.marks t = Teacher('Mrs. Shrividya', 40, 30000) s = Student('Swaroop', 22, 75) print # prints a blank line members = [t, s] for member in members: member.tell() # works for both Teachers and Students这个例子可以看出继承的基本含义。另外说一点,子类构造函数必须人工构造父类的构造函数,不能自动完成,这点与其他OOP语言有点区别。
4,I/O
4.1,文件你可以通过创建一个file类的对象来打开一个文件。
这个IO操作还是比较方便,能直接调用file()
#!/usr/bin/python # Filename: using_file.py poem = '''\ Programming is fun When the work is done if you wanna make your work also fun: use Perl! ''' f = file('poem.txt', 'w') # open for 'w'riting f.write(poem) # write text to file f.close() # close the file f = file('poem.txt') # if no mode is specified, 'r'ead mode is assumed by default while True: line = f.readline() if len(line) == 0: # Zero length indicates EOF break print line, # Notice comma to avoid automatic newline added by Python f.close() # close the file我们通过指明我们希望打开的文件和模式来 创建一个file类的实例。模式可以为读模式('r')、写模式('w')或追加模式('a')。事实上还有多得多的模式可以使用,你可以使用help(file)来了解它们的详情。
在一个循环中,我们使用readline方法读文件的每一行。这个方法返回包括行末换行符的一个完整行。所以,当一个 空的 字符串被返回的时候,即表示文件末已经到达了,于是我们停止循环。
这里面有个小疑问就是while语句的true是根据上下文来判断的么?我改成f也是可以的.
注意,因为从文件读到的内容已经以换行符结尾,所以我们在print语句上使用逗号来消除自动换行。最后,我们用close关闭这个文件。
4.2 存储器
Python提供一个标准的模块,称为pickle。使用它你可以在一个文件中储存任何Python对象,之后你又可以把它完整无缺地取出来。这被称为 持久地 储存对象。#!/usr/bin/python # Filename: pickling.py import cPickle as p #import pickle as p shoplistfile = 'shoplist.data' # the name of the file where we will store the object shoplist = ['apple', 'mango', 'carrot'] # Write to the file f = file(shoplistfile, 'w') p.dump(shoplist, f) # dump the object to a file f.close() del shoplist # remove the shoplist # Read back from the storage f = file(shoplistfile) storedlist = p.load(f) print storedlist首先,请注意我们使用了import..as语法。这是一种便利方法,以便于我们可以使用更短的模块名称。在这个例子中,它还让我们能够通过简单地改变一行就切换到另一个模块(cPickle或者pickle)!在程序的其余部分的时候,我们简单地把这个模块称为p。
#!/usr/bin/python # Filename: try_except.py import sys try: s = raw_input('Enter something --> ') except EOFError: print '\nWhy did you do an EOF on me?' sys.exit() # exit the program except: print '\nSome error/exception occurred.' # here, we are not exiting the program print 'Done'这个程序运行以后,按“Ctrl+C”或者“Ctrl+D”看看结果。。
#!/usr/bin/python # Filename: raising.py class ShortInputException(Exception): '''A user-defined exception class.''' def __init__(self, length, atleast): Exception.__init__(self) self.length = length self.atleast = atleast try: s = raw_input('Enter something --> ') if len(s) < 3: raise ShortInputException(len(s), 3) # Other work can continue as usual here except EOFError: print '\nWhy did you do an EOF on me?' except ShortInputException, x: print 'ShortInputException: The input was of length %d, \ was expecting at least %d' % (x.length, x.atleast) else: print 'No exception was raised.'这里,我们创建了我们自己的异常类型,其实我们可以使用任何预定义的异常/错误。这个新的异常类型是ShortInputException类。它有两个域——length是给定输入的长度,atleast则是程序期望的最小长度。
#!/usr/bin/python # Filename: finally.py import time try: f = file('poem.txt') while True: # our usual file-reading idiom line = f.readline() if len(line) == 0: break time.sleep(2) print line, finally: f.close() print 'Cleaning up...closed the file'睡了2秒,是故意延长时间,好让你按“Ctrl+C”,按了你也发现,文件还是关闭了最后。
#!/usr/bin/python # Filename: cat.py import sys def readfile(filename): '''Print a file to the standard output.''' f = file(filename) while True: line = f.readline() if len(line) == 0: break print line, # notice comma f.close() # Script starts from here if len(sys.argv) < 2: print 'No action specified.' sys.exit() if sys.argv[1].startswith('--'): option = sys.argv[1][2:] # fetch sys.argv[1] but without the first two characters if option == 'version': print 'Version 1.2' elif option == 'help': print '''\ This program prints files to the standard output. Any number of files can be specified. Options include: --version : Prints the version number --help : Display this help''' else: print 'Unknown option.' sys.exit() else: for filename in sys.argv[1:]: readfile(filename)这里面说明一下:argv自动将脚本文件名认为是argv[0],从0开始计数,与C语言一样,如果出现argv[1][2:]则是第二个参数,用户角度是第一个参数抛弃前两个字符,截取剩余字符的意思。
os.name字符串指示你正在使用的平台. os.getcwd()函数得到当前工作目录。 os.linesep字符串给出当前平台使用的行终止符。 os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录。类似地,os.path.existe()函数用来检验给出的路径是否真地存在。基本上python基本东西都在这里么了,当然讲的也是皮毛,在以后真正开发中我会不断添加内容和学习备忘的。