Python初探第三篇-面向对象
Posted ifyoushuai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python初探第三篇-面向对象相关的知识,希望对你有一定的参考价值。
类和对象
Pyhon中的类和对象与C++中的类和对象有着很大的差别,但是他们都是为了对一个对象的属性和方法进行封装,下面就具体讨论Pyhon的类和对象的使用方法。
class Foo: def __init__(num): self.num = num
f=Foo(1)
当使用类初始化对象时自动调用__init__()方法。
二,类属性和实例属性
类属性可以通过实例对象或者类本身去调用
class Foo: name = "isFoo" def __init__(self): pass f = Foo print(f.name) #isFoo print(Foo.name)#isFoo
实例属性可以通过构造函数来绑定,也可以直接绑定
class Foo: def __init__(self,name): self.name = name f = Foo("Jack") f.age = 18
print(f.name) #Jack #实例属性可以通过属性字典来查看 print(f.__dict__) #{‘name‘: ‘Jack‘, ‘age‘: 18}
注意事项:
1,类属性只能通过类调用去修改
2,若用实例区修改类属性,将直接设置一个与类属性同名的实例属性
三,继承
Python3全部是新式类,即类无论是否继承object类,都默认继承它。
class Animal: def eat(self): print("%s eating sth" % self.name) class Cat(Animal): def __init__(self, name): self.name = name c = Cat("miaomiao") c.eat() # miaomaio eating sth
子类若没有构造函数,则使用父类的构造函数,若有,即有两种方式来调用父类的构造函数
class Animal: def __init__(self,age): self.age=age def eat(self): print("%s eating sth" % self.name) class Cat(Animal): def __init__(self, name,age): # Animal.__init__(self,age) #first super().__init__(age) #second self.name = name
抽象类
四,组合与重用
当几个类有着共同的属性时,我们可以将共同的部分抽象出来当做父类,而组合则是一种所有关系,如学校与老师,班级与学生。
class Student: def __init__(self,name,age): self.name=name self.age=age class class_grade: def __init__(self): self.li=[] def put(self,name,age): self.li.append(Student(name, age)) c=class_grade() c.put("Jack",18) print(c.li[0].name,c.li[0].age) #Jack 18
五,封装
封装具有两个特点:
将属性和方法封装在一个对象中,隐藏细节,仅提供接口;
具有访问控制;
第一个特点在前文已经阐述完了,我们来看Python类中的访问控制。
在Python中并没有真正的限制类的外部或者是子类对类内部数据的访问,而是一种约定,一种隐藏不直接暴露。
通过双下划线来隐藏
class Foo: __N=2 def __init__(self): self.__name="Jack" def func(self): print(self.__N) #0 print(self.__name) #Jack 类的内部可以直接通过名字访问 f=Foo() f.func() # print(self.__name) name #‘self‘ is not defined # print(f.__N) #‘Foo‘ object has no attribute ‘__N‘ print(f._Foo__N) #可以通过_类名__变量名 访问 实例属性和函数属性同理
这种变形需要注意的问题是:
1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N,即这种操作并不是严格 意义上的限制外部访问,
仅仅只是一种语法意义上的变形,主要用来限制外部的直接访问。
2.变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形
那么我们可以用以下方法来给外部提供一个方法,使类外面对私有变量友好访问
property(特性)
class Foo: __N = 2 def __init__(self): self.__name = "Jack" @property #访问 def name(self): return self.__name @name.setter #设置值 def name(self, value): if not isinstance(value, str): print("请输入字符串类型") else: self.__name = value @name.deleter #删除 def name(self): del self.__name f = Foo()
print(f.name) #像是调用属性,实则调用方法,也符合实际
f.name="Bob"
del f.name
通过实现不同的函数就能实现不同的访问控制
六,多态
我们先回顾一下C++中的多态:父类指针(引用)指向(引用)子类或者父类对象时,会根据实际对象的类型来调用不同的方法。而在python中,由于都是动态数据类型,赋值的时候就是初始化,因此多态更偏向一种代码逻辑而不是语法。
class demo1: def display(self): print("这是demo1") class demo2: def display(self): print("这是demo2") class demo3: def display(self): print("这是demo3") def func(obj): obj.display() if __name__ == ‘__main__‘: d1 = demo1() d2 = demo2() d3 = demo3() # ---调用同一个函数的不同表现形态-- func(d1) # 这是demo1 func(d2) # 这是demo2 func(d3) # 这是demo3
以上是关于Python初探第三篇-面向对象的主要内容,如果未能解决你的问题,请参考以下文章