标签:ntp 学习 包括 替换 module 执行 代码 ref trace
与python的函数定义类似,只不过把def关键字替换为class
class calculator():
pass
a=calculator()
print(type(a))
输出
<class ‘main.calculator‘>
与php的定义类似,只不过把__construct替换成__init__
class calculator():
def __init__(self,x,y):
self.x=x
self.y=y
a=calculator(1,2)
print(a.x)
print(a.y)
输出
1
2
这里需要注意的是self,这里的self与C++中的对象指针或者JAVA中的对象引用是一样的,用途都是类作用域内提供对当前类对象的引用,但写法上有很大区别。在python中定义类的时候,类的所有函数,包括构造函数,首个参数都必须为self。
python中继承的写法同样简单,在类定义的括号里加入父类的类名就可以了。
class game():
def play(self):
print("start play a game")
class RPG(game):
def chooseACareer(self):
print("choose your career")
class FPS(game):
def shoot(self):
print("shoot enemy")
game=game()
rpgGame=RPG()
fpsGame=FPS()
game.play()
rpgGame.play()
rpgGame.chooseACareer()
fpsGame.play()
fpsGame.shoot()
输出
start play a game
start play a game
choose your career
start play a game
shoot enemy
请按任意键继续. . .
可以通过在子类中定义重名函数对父类函数进行重写
class game():
def play(self):
print("start play a game")
class RPG(game):
def play(self):
print("start play a RPG game")
def chooseACareer(self):
print("choose your career")
class FPS(game):
def play(self):
print("start play a FPS game")
def shoot(self):
print("shoot enemy")
game=game()
rpgGame=RPG()
fpsGame=FPS()
game.play()
rpgGame.play()
rpgGame.chooseACareer()
fpsGame.play()
fpsGame.shoot()
输出
start play a game
start play a RPG game
choose your career
start play a FPS game
shoot enemy
请按任意键继续. . .
可以通过调用super()
获取父类句柄进而执行父类函数
class game():
def play(self):
print("start play a game")
class RPG(game):
def play(self):
super().play()
print("start play a RPG game")
def chooseACareer(self):
print("choose your career")
class FPS(game):
def play(self):
super().play()
print("start play a FPS game")
def shoot(self):
print("shoot enemy")
game=game()
rpgGame=RPG()
fpsGame=FPS()
game.play()
rpgGame.play()
rpgGame.chooseACareer()
fpsGame.play()
fpsGame.shoot()
输出
start play a game
start play a game
start play a RPG game
choose your career
start play a game
start play a FPS game
shoot enemy
请按任意键继续. . .
如果不是我搞错了的话,这个特性应该是我目前所知的所有编程语言中的独一份,无论是C++,JAVA还是PHP,他们统统是不支持多继承的,如果要给一个类附加多种特性,唯一的选择就是在单继承的基础上结合多个接口,从继承关系树来看这么做也是有必要的,如果一个类有多个父类,那类之间的继承关系将相当复杂,而且互相之间的重名问题也将难以理清。但是,python是支持的,在没有对这个特性更多深入理解的情况下不便做更多阐述,在这里我们先知道python的这一特性便可。
class game():
def play(self):
print("start play a game")
class RPG(game):
def play(self):
super().play()
print("start play a RPG game")
def chooseACareer(self):
print("choose your career")
class FPS(game):
def play(self):
super().play()
print("start play a FPS game")
def shoot(self):
print("shoot enemy")
class RPGandFPSGame(RPG,FPS):
pass
xgame=RPGandFPSGame()
xgame.play()
xgame.chooseACareer()
xgame.shoot()
输出
start play a game
start play a FPS game
start play a RPG game
choose your career
shoot enemy
请按任意键继续. . .
这个代码示例的输出相当具有迷惑性,看起来xgame的play方法同时兼具两个父类的play方法的效果,但也不是先后执行的样子,因为game的play方法只执行了一次。在经过调试后可以发现,实际上现在的类继承级别变成了这样:RPGandFPSGame=>RPG=>FPS=>game,有兴趣的可以对6、12行代码注释后调试代码进行验证。
与JAVA类似,python也支持对对象的类型判断
class game():
def play(self):
print("start play a game")
class RPG(game):
def play(self):
super().play()
print("start play a RPG game")
def chooseACareer(self):
print("choose your career")
class FPS(game):
def play(self):
super().play()
print("start play a FPS game")
def shoot(self):
print("shoot enemy")
class RPGandFPSGame(RPG,FPS):
pass
xgame=RPGandFPSGame()
xgame.play()
xgame.chooseACareer()
xgame.shoot()
print(isinstance(xgame,game))
print(isinstance(xgame,RPG))
print(isinstance(xgame,FPS))
print(isinstance(xgame,RPGandFPSGame))
输出
start play a game
start play a FPS game
start play a RPG game
choose your career
shoot enemy
True
True
True
True
请按任意键继续. . .
在其它高级语言中,访问修饰符绝对是面向对象内容中的重点之一,会衍生出众多问题。但是,python中完全没有!对,python的所有对象属性的访问权限都是public,只不过存在所谓的伪私有属性这种情况。
class ClassAcess():
def __init__(self):
self.publicMember="public member"
self.__privateMember="private member"
a=ClassAcess()
print(a.publicMember)
print(a.__privateMember)
输出
public member
Traceback (most recent call last):
File "D:\workspace\python\test.py", line 7, in
print(a.__privateMember)
AttributeError: ‘ClassAcess‘ object has no attribute ‘__privateMember‘
请按任意键继续. . .
可以看到,对类对象命名时加上双下划线就可以起到类似访问限定符private的作用
class ClassAcess():
def __init__(self):
self.publicMember="public member"
self.__privateMember="private member"
#a=ClassAcess()
#print(a.publicMember)
#print(a.__privateMember)
class SubClassAcess(ClassAcess):
def printParentPrivateMember(self):
print(super().__privateMember())
b=SubClassAcess()
b.printParentPrivateMember()
输出
Traceback (most recent call last):
File "D:\workspace\python\test.py", line 12, in
b.printParentPrivateMember()
File "D:\workspace\python\test.py", line 10, in printParentPrivateMember
print(super().__privateMember())
AttributeError: ‘super‘ object has no attribute ‘_SubClassAcess__privateMember‘
请按任意键继续. . .
可以看出子类也是不能访问的,的确起到了和private限定符类似的作用。
class ClassAcess():
def __init__(self):
self.publicMember="public member"
self.__privateMember="private member"
a=ClassAcess()
print(a.publicMember)
print(a._ClassAcess__privateMember)
class SubClassAcess(ClassAcess):
def printParentPrivateMember(self):
print(super()._ClassAcess__privateMember)
b=SubClassAcess()
b.printParentPrivateMember()
输出
public member
private member
Traceback (most recent call last):
File "D:\workspace\python\test.py", line 12, in
b.printParentPrivateMember()
File "D:\workspace\python\test.py", line 10, in printParentPrivateMember
print(super()._ClassAcess__privateMember)
AttributeError: ‘super‘ object has no attribute ‘_ClassAcess__privateMember‘
请按任意键继续. . .
可以看出,在访问时候加上\_类名
就可以直接访问了,但是子类依然不能访问。所以说python中的访问限定只是一种伪私有方式,是一种约定俗成的类对象命名规则。其实质上是通过替换类属性的访问时名称来实现对类属性的访问保护。更多的介绍可以阅读这里。
总结一下类属性的特殊命名
__memberName等效于private
_memberName等效于protected
__memberName__属于系统特殊定义,比如构造函数
标签:ntp 学习 包括 替换 module 执行 代码 ref trace
原文地址:https://www.cnblogs.com/Moon-Face/p/14455323.html