您的位置:首页 > 编程语言 > Python开发

python 系统学习笔记(十)---类

2013-09-27 16:14 351 查看
self
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是在调用这个
方法的时候你不为这个参数赋值,Python会提供这个值。这个特别的变量指对象本身,按照惯例它的名称
是self。
虽然你可以给这个参数任何名称,但是 强烈建议 你使用self这个名称——其他名称都是不赞成你使用
的。
Python中的self等价于C++中的self指针和Java、C#中的this参考。
你一定很奇怪Python如何给self赋值以及为何你不需要给它赋值。举一个例子会使此变得清晰。假如你
有一个类称为MyClass和这个类的一个实例MyObject 。当你调用这个对象的方
法MyObject.method(arg1, arg2) 的时候,这会由Python自动转
为MyClass.method(MyObject, arg1, arg2) ——这就是self的原理了。
这也意味着如果你有一个不需要参数的方法,你还是得给这个方法定义一个self参数。类对象支持两种操作:属性引用和实例化。属性引用使用和Python中所有的属性引用一样的标准语法:
obj.name
。类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:
class MyClass:
"A simple example class"
i = 12345
def f(self):
return 'hello world'

那么
MyClass.i
MyClass.f
是有效的属性引用,分别返回一个整数和一个方法对象。也可以对类属性赋值,你可以通过给
MyClass.i
赋值来修改它。__doc__ 也是一个有效的属性,返回类的文档字符串:“
A
simple example class
”。类的实例化使用函数符号。只要将类对象看作是一个返回新的类实例的无参数函数即可。例如(假设沿用前面的类):
x = MyClass()

以上创建了一个新的类实例并将该对象赋给局部变量x。这个实例化操作(“调用”一个类对象)来创建一个空的对象。很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为__init__() 的特殊方法,像下面这样:
def __init__(self):
self.data = []

类定义了 __init__() 方法的话,类的实例化操作会自动为新创建的类实例调用 __init__() 方法。所以在下例中,可以这样创建一个新的实例:
x = MyClass()

当然,出于弹性的需要, __init__() 方法可以有参数。事实上,参数通过 __init__()传递到类的实例化操作上。__init__方法在Python的类中有很多方法的名字有特殊的重要意义。现在我们将学习__init__ 方法的意义。__init__ 方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。注意,这个名称的开始和结尾都是双下划线。使用__init__方法[python] view
plaincopyclass SayHello:def __init__(self,hellostr):self.data = hellostrdef sayHi(self,histr):print 'hi'x=SayHello("hello world")print '%s' %(x.data)x.sayHi('hi')
第一种称作数据属性。这相当于Smalltalk中的“实例变量”或C++中的“数据成员”。和局部变量一样,数据属性不需要声明,第一次使用时它们就会生成self.data 就是数据属性第二种方法属性通常方法是直接调用的:
x.sayHi('hi')

在我们的例子中,这会返回字符串‘
hi’
继承当然,如果一种语言不支持继承就,“类”就没有什么意义。派生类的定义如下所示:
class DerivedClassName(BaseClassName):.
.
.
命名 BaseClassName (示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:
class DerivedClassName(modname.BaseClassName):
派生类定义的执行过程和基类是一样的。构造派生类对象时,就记住了基类。这在解析属性引用的时候尤其有用:如果在类中找不到请求调用的属性,就搜索基类。如果基类是由别的类派生而来,这个规则会递归的应用上去。派生类的实例化没有什么特殊之处:
DerivedClassName()
(示列中的派生类)创建一个新的类实例。方法引用按如下规则解析:搜索对应的类属性,必要时沿基类链逐级搜索,如果找到了函数对象这个方法引用就是合法的。派生类可能会覆盖其基类的方法。因为方法调用同一个对象中的其它方法时没有特权,基类的方法调用同一个基类的方法时,可能实际上最终调用了派生类中的覆盖方法。(对于C++程序员来说,Python中的所有方法本质上都是虚方法。)派生类中的覆盖方法可能是想要扩充而不是简单的替代基类中的重名方法。有一个简单的方法可以直接调用基类方法,只要调用:“BaseClassName.methodname(self, arguments)”。有时这对于客户也很有用。(要注意的中只有基类在同一全局作用域定义或导入时才能这样用。)[python] view
plaincopy#!/usr/bin/python# Filename: inherit.pyclass SchoolMember:'''''Represents any school member.'''def __init__ (self, name, age):self.name = nameself.age = ageprint '(Initialized SchoolMember: %s)' %self.namedef 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 = salaryprint '(Initialized Teacher: %s)' % self.namedef tell(self):SchoolMember.tell(self)print 'Salary: "%d"' % self.salaryclass Student(SchoolMember):'''''Represents a student.'''def __init__ (self, name, age, marks):SchoolMember.__init__(self, name, age)self.marks = marksprint '(Initialized Student: %s)' % self.namedef tell(self):SchoolMember.tell(self)print 'Marks: "%d"' % self.markst = Teacher('Mrs. Shrividya' , 40, 30000)s = Student('Swaroop', 22, 75)print # prints a blank linemembers = [t, s]for member in members:member.tell() # works for both Teachers and Students四、运算符重载重载的关键概念*运算符重载让类拦截常规的Python运算。*类可重载所有Python表达式运算。*类可重载打印,函数调用,属性点号运算等运算。*重载使类实例的行为像内置类型。*重载是通过提供特殊名称的类方法来实现的。如果类中提供了某些特殊名称的方法,当类实例出现在运算有关的表达式的时候,Python就会自动调用这些方法。1、 常见的运算符重载方法方法 重载 调用__init__ 构造器方法 对象建立:X=Class()__del__ 析构方法 对象收回__add__ 运算符+ X+Y,X+=Y__sub__ 运算符- X-Y,X-=Y__or__ 运算符|(位OR) X|Y X|=Y__repr__,__str__ 打印,转换 print X【__str__】、repr(X)、str(X)__call__ 函数调用 X()__getattr__ 点号运算 X.undefined__setattr__ 属性赋值语句 X.any=Value__getitem__ 索引运算 X[key],没有__iter__时的for循环和其他迭代器__setitem__ 索引赋值语句 X[key]=value__len__ 长度 len(X),真值测试__cmp__ 比较 X==Y,X__lt__ 特定的比较 X<Y(or else __cmp__)__eq__ 特定的比较 X==Y(or else __cmp__)__radd__ 左侧加法 + Noninstance + X__iadd__ 实地(增强的)的加法 X+=Y(or else __add__)__iter__ 迭代环境 用于循环,测试,列表,映射及其他所有重载方法的名称前后都有两个下划线字符,以便把同类中定义的变量名区别开来。特殊方法名称和表达式或运算的映射关系,是由Python语言预先定义好的。所有运算符重载的方法都是选用的:如果没有写某个方法,那么定义的类就不支持该运算。多数重载方法只用在需要对象行为表现得就像内置函数一样的高级程序中。然而,__init__构造方法常出现在绝大多数类中。__getitem__拦截索引运算__getitem__方法拦截实例的索引运算。当实例X出现X[i]这样的索引运算中时,Python会调用这个实例继承的__getitem__方法。(如果有),把X作为第一个参数传递,并且放括号内的索引值传递给第二个参数python实现 单例模式[python] view
plaincopy#!/usr/bin/env python# -*- coding:utf-8 -*-import osclass IOLoop(object):@classmethoddef instance(self):if not hasattr(self, "_instance"):self._instance = self()return self._instance@classmethoddef initialized(self):"""Returns true if the singleton instance has been created."""return hasattr(self, "_instance")def service(self):print 'Hello,World'print IOLoop.initialized()ioloop = IOLoop.instance()ioloop.service()#if os.fork() == 0:print IOLoop.initialized()ioloop = IOLoop.instance()ioloop.service()练习题写一个类继承一个基类[python] view
plaincopy# Creating a class hierarchy with an abstract base class.class Employee:"""Abstract base class Employee"""def __init__(self, first, last):"""Employee constructor, takes first name and last name.NOTE: Cannot create object of class Employee."""if self.__class__ == Employee:raise NotImplementedError,"Cannot create object of class Employee"self.firstName = firstself.lastName = lastdef __str__(self):"""String representation of Employee"""return "%s %s" % (self.firstName, self.lastName)def _checkPositive(self, value):"""Utility method to ensure a value is positive"""if value < 0:raise ValueError,"Attribute value (%s) must be positive" % valueelse:return valuedef earnings(self):"""Abstract method; derived classes must override"""raise NotImplementedError, "Cannot call abstract method"class Boss(Employee):"""Boss class, inherits from Employee"""def __init__(self, first, last, salary):"""Boss constructor, takes first and last names and salary"""Employee.__init__(self, first, last)self.weeklySalary = self._checkPositive(float(salary))def earnings(self):"""Compute the Boss's pay"""return self.weeklySalarydef __str__(self):"""String representation of Boss"""return "%17s: %s" % ("Boss", Employee.__str__(self))class CommissionWorker(Employee):"""CommissionWorker class, inherits from Employee"""def __init__(self, first, last, salary, commission, quantity):"""CommissionWorker constructor, takes first and last names,salary, commission and quantity"""Employee.__init__(self, first, last)self.salary = self._checkPositive(float(salary))self.commission = self._checkPositive(float(commission))self.quantity = self._checkPositive(quantity)def earnings(self):"""Compute the CommissionWorker's pay"""return self.salary + self.commission * self.quantitydef __str__(self):"""String representation of CommissionWorker"""return "%17s: %s" % ("Commission Worker",Employee.__str__(self))class PieceWorker(Employee):"""PieceWorker class, inherits from Employee"""def __init__(self, first, last, wage, quantity):"""PieceWorker constructor, takes first and last names, wageper piece and quantity"""Employee.__init__(self, first, last)self.wagePerPiece = self._checkPositive(float(wage))self.quantity = self._checkPositive(quantity)def earnings(self):"""Compute PieceWorker's pay"""return self.quantity * self.wagePerPiecedef __str__(self):"""String representation of PieceWorker"""return "%17s: %s" % ("Piece Worker",Employee.__str__(self))class HourlyWorker(Employee):"""HourlyWorker class, inherits from Employee"""def __init__(self, first, last, wage, hours):"""HourlyWorker constructor, takes first and last names,wage per hour and hours worked"""Employee.__init__(self, first, last)self.wage = self._checkPositive(float(wage))self.hours = self._checkPositive(float(hours))def earnings(self):"""Compute HourlyWorker's pay"""if self.hours <= 40:return self.wage * self.hourselse:return 40 * self.wage + (self.hours - 40) * self.wage * 1.5def __str__(self):"""String representation of HourlyWorker"""return "%17s: %s" % ("Hourly Worker",Employee.__str__(self))# main program# create list of Employeesemployees = [ Boss("John", "Smith", 800.00),CommissionWorker("Sue", "Jones", 200.0, 3.0, 150),PieceWorker("Bob", "Lewis", 2.5, 200),HourlyWorker("Karen", "Price", 13.75, 40) ]# print Employee and compute earningsfor employee in employees:print "%s earned $%.2f" % (employee, employee.earnings())
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: