类
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
通过定义一些简单的 Python 类,来学习 Python 面向对象编程的基本概念
1.定义类
class nameoftheclass(parent_class): statement1 statement2 statement3
在类的声明中你可以写任何 Python 语句,包括定义函数(在类中我们称为方法)
>>> class MyClass(object): ... """A simple example class""" ... i = 12345 ... def f(self): ... return 'hello world'
2. __init__ 方法
类的实例化使用函数符号。只要将类对象看作是一个返回新的类实例的无参数函数即可。例如(假设沿用前面的类):
x = MyClass()
以上创建了一个新的类实例并将该对象赋给局部变量 x
当然,出于弹性的需要,__init__() 方法可以有参数。事实上,参数通过__init__() 传递到类的实例化操作上
>>> class Complex: ... def __init__(self, realpart, imagpart): ... self.r = realpart ... self.i = imagpart ... >>> x = Complex(3.0, -4.5) >>> x.r, x.i (3.0, -4.5)
3. 继承
当一个类继承另一个类时,它将继承父类的所有功能(如变量和方法)。这有助于重用代码。
在下一个例子中我们首先创建一个叫做 Person 的类,然后创建两个派生类 Student 和 Teacher。当两个类都从 Person 类继承时,它们的类除了会有 Person 类的所有方法还会有自身用途的新方法和新变量。
#! /usr/bin/python #coding=utf-8 class Person(object): '''返回固定的值''' def __init__(self,name): self.name = name def get_details(self): '''返回包含人名的字符串''' return self.name class Student(Person): '''返回student 对象,采用name,branch.year 3个参数''' def __init__(self,name,branch,year): Person.__init__(self,name) self.branch = branch self.year = year def get_details(self): '''返回学生的详细信息''' return "{} studies {} and is in {} year .".format(self.name,self.branch,self.year) class Teacher(Person): '''返回老师对象''' def __init__(self,name,papers): Person.__init__(self,name) self.papers = papers def get_details(self): return "{} teaches {}".format(self.name, ','.join(self.papers)) person1 = Person('Sachin') student1 = Student('Kushal', 'CSE', 2005) teacher1 = Teacher('Prashad', ['C', 'C++']) print(person1.get_details()) print(student1.get_details()) print(teacher1.get_details()) [test@iZuf60gzvn9k0h3fuhr6y5Z python]$ ./test.py Sachin Kushal studies CSE and is in 2005 year . Prashad teaches C,C++
在这个例子中你能看到我们是怎样在 Student 类和 Teacher 类中调用 Person 类的 __init__ 方法。
我们也在 Student 类和 Teacher 类中重写了 Person 类的 get_details() 方法。
因此,当我们调用 student1 和 teacher1 的 get_details() 方法时,使用的是各自类(Student 和 Teacher)中定义的方法。
4. 多继承
一个类可以继承自多个类,具有父类的所有变量和方法,语法如下:
class MyClass(Parentclass1, Parentclass2,...): def __init__(self): Parentclass1.__init__(self) Parentclass2.__init__(self) ... ...
5. 删除对象
del
>>> s = "I love you" >>> del s >>> s Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 's' is not defined
6.属性的读取方法
在 Python 里请不要使用属性(attributes)读取方法(getters 和 setters)。如果你之前学过其它语言(比如 Java),你可能会想要在你的类里面定义属性读取方法。请不要这样做,直接使用属性就可以了,就像下面这样:
>>> class Student(object): ... def __init__(self, name): ... self.name = name ... >>> std = Student("Kushal Das") >>> print(std.name) Kushal Das >>> std.name = "Python" >>> print(std.name) Python
7.装饰器
你可能想要更精确的调整控制属性访问权限,你可以使用 @property 装饰器,@property 装饰器就是负责把一个方法变成属性调用的。
@property本身又会创建另外一个装饰器@score.setter,负责把set方法变成给属性赋值,这么做完后,我们调用起来既可控又方便
下面有个银行账号的例子,我们要确保没人能设置金额为负,并且有个只读属性 cny 返回换算人名币后的金额。
#! /usr/bin/python #coding=utf-8 class Account(object): """账号类,amount是美元金额""" def __init__(self,rate): self.__amt = 0 self.rate = rate @property def amount(self): '''账号余额美元''' return self.__amt @property def cny(self): '''账号余额人民币''' return self.__amt*self.rate @amount.setter def amount(self,value): if value < 0 : print("账号余额不能小于0") return self.__amt = value if __name__ == '__main__': acc = Account(rate=6.8) acc.amount = 20 print("Dollar amount:", acc.amount) print("In CNY:", acc.cny) acc.amount = -100 print("Dollar amount:", acc.amount)
[test@iZuf60gzvn9k0h3fuhr6y5Z python]$ ./test.py Dollar amount: 20 In CNY: 136.0 账号余额不能小于0 Dollar amount: 20