python学习(三)面向对象
来源:互联网 发布:河南用友软件总代理 编辑:程序博客网 时间:2024/05/17 19:58
python面向对象
继承
class Person(object): ''' classdocs ''' def __init__(self,name): ''' Constructor ''' self.name = nameclass Student(Person): def __init__(self,age,score): self.age = age self.score = score def printInfo(self): print("name is :%s age is :%s score is :%s" %(self.name, self.age,self.score))student = Student(22,89)student.name = "test"student.printInfo()
以上Person类继承自object,并且有一个name属性,Student类继承自Person,定义了一个printInfo方法,用来打印信息,此时运行效果如下:
私有属性
在python中,给变量名称前面增加两个下划线,表示该变量是一个私有的变量
class Student(Person): def __init__(self,age,score): self.__age = age self.score = score def printInfo(self): print("name is :%s age is :%s score is :%s" %(self.name, self.age,self.score))
上面age表示私有属性,不能通过对象来设置值,只能在类内部操作
为私有变量设置get和set方法
class Student(Person): def __init__(self,age,score): self.__age = age self.__score = score def printInfo(self): print("name is :%s age is :%s score is :%s" %(self.name, self.__age,self.__score)) def set_age(self,age): self.__age = age def get_age(self): return self.__agestudent = Student(22,89)student.name = "test"student.set_age(30)student.printInfo()print("age is :%s" %(student.get_age()))
其实对于私有变量,也不是一定必须要通过get方法来获取,对于上面的栗子,python解释器将其解释成了_Student__age,所以,我们依然可以通过这个属性来访问
print("age is :%s" %(student._Student__age)) # 输出: age is :30
需要注意下面问题
上面我们通过self.__age = age 将age属性表示为私有属性,但是有的同学发现好像还是可以通过下面的代码来设置的
student.age = 12
其实这个是不对的,前面已经说过了,对于私有属性__age,python解释器将其解释为_Student__age,上面的代码,就相当于为student对象的name属性赋值
获取对象信息
可以使用type函数获取当前对象的类型
print type(Student(22,50))print type(23)print type("string")print type(22.0)
判断是否是某个类的实例
python中同样提供了isinstance函数来判断一个对象是否是一个类的实例
print isinstance(Student(22,88),Person) #输出: True
hasattr和setattr
python中提供了setattr来为对象设置一个新的属性,hasattr判断是否有一个指定的属性
student = Student(22,88)print hasattr(student,"score")setattr(student,"year","1990") # 输出 Trueprint student.year # 输出 1990
类属性
上面的所有属性都是通过self或者对象本身创建的属性,这些都是对象属性,那么同样在python中可以创建一个类似于java中的static属性,我们称之为类属性
class Student(Person): password = "Student pass"print("类属性 password is :%s" %(Student.password)) # 输出: 类属性 password is :Student passStudent.password = "a new pass"print("类属性 password is :%s" %(Student.password)) # 输出: 类属性 password is :a new pass
实例属性的优先级高于类属性
给实例绑定方法
from types import MethodType class Student(object): password = "Student pass" def __init__(self,age,score): self.age = age self.score = score def printInfo(self): print("age is :%s score is :%s" %(self.age,self.score))def set_age(self,age): self.age = agestudent = Student(22,88)student.name = "王五"student.printInfo()# 使用MethodType为实例绑定方法,注意需要引入对应的模块student.set_age = MethodType(set_age,student);student.set_age(44)student.printInfo()
上面使用MethodType虽然可以为实例绑定一个方法,但是这个方法对于另外一个实例是没有效果的,比如:如果我们重新创建一个实例,并且执行上一步绑定的方法,此时会抛出如下错误:
studentSecond = Student(23,88)studentSecond.set_age(44)
为了解决上面的问题,我们可以给整个class绑定方法,这样该类的所有实例都可以访问这样的方法了
def set_age(self,age): self.age = ageStudent.set_age = set_agestudent = Student(22,88)student.name = "王五"student.printInfo()student.set_age = MethodType(set_age,student);student.set_age(44)student.printInfo()studentSecond = Student(23,88)studentSecond.set_age(55)studentSecond.printInfo()
限制类绑定的属性
# 我们可以使用__slots__在当前类中声明属性,这样的话,当前类的所有实例就只能绑定声明中已有的属性class Person(object): ''' classdocs ''' def __init__(self,name): ''' Constructor ''' self.name = nameclass Student(object): __slots__ = ["age","score"] def printInfo(self): print("age is :%s score is :%s" %(self.age,self.score))student = Student()student.age = 22student.score = 33# 试图绑定name属性student.name = "wangwu"student.printInfo()
可以看到这里,我们限定当前类只能绑定age和score属性,此时当程序试图绑定name属性的时候,就会出现错误
需要注意的是绑定属性对于当前类的子类是没有效果的,看下面栗子
class SubStudent(Student): passsubStudent = SubStudent()subStudent.age = 33subStudent.score = 55subStudent.name = "xiaolizi"subStudent.printInfo()print subStudent.name
把方法变成属性
我们可以通过”@property”
class Student(object): @property def age(self): return self._age @age.setter def age(self,value): self._age= value def printInfo(self): print("age is :%s score is :%s" %(self.age,self.score))student = Student()student.age = 55print student.age # 输出: 55
python多继承
另外在python中是支持多继承的,看下面的栗子
class Person(object): ''' classdocs ''' def __init__(self,name): ''' Constructor ''' self.name = nameclass MusicTeacher(Person): def learnMusic(self): print "student need to learn music"class MathTeacher(Person): def learnMath(self): print "student need to learn math"class Student(MusicTeacher,MathTeacher): @property def age(self): return self._age @age.setter def age(self,value): self._age= value def printInfo(self): print("name is :%s age is :%s" %(self.name,self.age))student = Student("张三")student.age = 55student.printInfo()student.learnMath()student.learnMusic()
学生会学习音乐和数学这两门课程,此时运行效果如下:
重写”toString”
这里之所以给”toString”添加上双引号,是因为这里实际并不是一个toString方法,看下面栗子
class Student(MusicTeacher,MathTeacher): @property def age(self): return self._age @age.setter def age(self,value): self._age= valuestudent = Student("张三")student.age = 55print student
这里此时打印如下:
可以看到,这里和java中一样,打印的是student实例的内存地址,不过我们可以通过添加像java中的toString方法
def __str__(self): return "student name is :"+self.name
此时效果如下:
对实例进行调用
另外,在python中可以直接调用对象,只需要为当前类添加如下方法的实现即可:
__call__()
看下面栗子:
class Student(MusicTeacher,MathTeacher): @property def age(self): return self._age @age.setter def age(self,value): self._age= value def __call__(self): print "This is student self call...."student = Student("张三")student.age = 55student()
枚举实现
在python中,同样支持枚举类型,在3.6上直接支持,我的是在2.7上的实现,看下面栗子
def enum(**enums): return type('Enum', (), enums)Weeks = enum(MONDY=1, TUESDAY=2, WENSDAY='three')print str(Weeks.MONDY)+" "+str(Weeks.TUESDAY)+" "+Weeks.WENSDAY
动态创建一个类
在python中,可以通过type动态创建一个类,看下面栗子
def sayHello(self): print "hello world"Hello = type('Hello', (object,), dict(sayHello=sayHello)) # 创建Hello classhello = Hello()hello.sayHello() # 输出: hello world
python中常见的特殊函数
python中的特殊方法,有如下特点:
- 特殊方法定义在class中
- 不需要直接调用
- python的某些函数或操作符会调用对应的特殊方法
- 在实现某一个特殊方法的时候,关联的特殊方法必须同时实现
在之前的学习中,我们每次打印一个对象,比如list
class Person(object): def __init__(self,name): self.name = nameperson = Person("王五")print personb = ["alice","tom","jerry","xiaoming"]print b
这是因为任何一个数据类型都有一个下面的方法
"__str__()"
上面的操作其实就等同于
person = Person("王五")print person.__str__()b = ["alice","tom","jerry","xiaoming"]print b.__str__()
获取类的特殊方法
在python中,可以通过dir方法来获取某一类对象所拥有的特殊方法
print dir(person)['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']
- python学习(三)面向对象
- python学习笔记(三)面向对象
- python学习:面向对象
- Python面向对象学习
- Python学习-面向对象
- Python学习14:面向对象编程(三)
- python学习笔记(三)之面向对象编程
- python学习(八):面向对象(三)
- python学习-面向对象进阶之元类(三)
- Python学习笔记(三)——模块|面向对象
- Python学习笔记(三)函数、面向对象、模块发布
- Java4Android学习三 - 面向对象
- Python学习 面向对象编程
- python 学习笔记--面向对象
- python学习之--面向对象
- Python学习----面向对象编程
- Python学习之面向对象
- Python面向对象学习(2)
- 主成分分析(PCA)
- 2008年分区联赛提高组第三题 传纸条
- Linux系统常见的目录说明
- leetcode
- android studio external tool + ndk测试
- python学习(三)面向对象
- Java中回调的简单理解
- [ windows程序设计(programing windows) ]
- 菜鸟读文献系列(三)
- Android_lottery_write&readSdcard.
- 初学JSP与Servlet之登录界面2.0版本
- 算法笔记_055-蓝桥杯练习 Tricky and Clever Password (Java)
- 设计原则和设计模式的理解
- C# string