Python入门(三)-面向对象

一、创建类

class Student:
    name = "jack"#属性
    age = 18 #公有属性
    __private_sttrs = ""#两个下划线开头,声明该属性为私有

def __init__(self,age):#__init__是构造方法
    self.age = age
    print ("init")

def __private_method(self):#两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用
    print "private method"

def setName(self,name):#方法
   self.name = name
   print("setName")

stu = Student(20)#创建实例对象
stu.setName("jim")#调用方法

print stu.name
print stu.age

self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
self 不是 python 关键字,只是习惯用这个命名表示类的实例,我们把他换成 runoob 也是可以正常执行

class Test:
    def prt(self):
        print(self)
        print(self.__class__)


t = Test()
t.prt()

二、添加,删除,修改类的属性

stu.gender = "male" #类中没有gender属性,直接添加属性
stu.gender = "female"#修改属性
del stu.gender #删除属性

三、访问属性的函数方法
你也可以使用以下函数的方式来访问属性:
getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。

hasattr(stu, "age")    # 如果存在 'age' 属性返回 True。
getattr(stu, "age")    # 返回 'age' 属性的值
setattr(stu, "age", 8) # 添加属性 'age' 值为 8
delattr(stu, "age")    # 删除属性 'age'

四、Python内置类属性
dict : 类的属性(包含一个字典,由类的数据属性组成)
doc :类的文档字符串
name: 类名
module: 类定义所在的模块(类的全名是'main.className',如果类位于一个导入模块mymod中,那么 className.module 等于 mymod)
bases : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

print Student.__dict__
print Student.__doc__
print Student.__name__
print Student.__module__
print Student.__bases__
输出结果:
 {'__module__': '__main__', 'name': 'jack', 'setName': <function setName at 
 0x1096c37d0>, 'age': 18, '__doc__': None, '__init__': <function __init__ at 
 0x1096c3758>}
 None
 Student
 __main__
 ()

五、类的继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。
需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写在括号里,基本类是在类定义的时候,在元组之中指明的。
在python中继承中的一些特点:
1:在继承中基类的构造(init()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别在于类中调用普通函数时并不需要带上self参数
3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。
语法:
派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:

 class SubClassName (ParentClass1[, ParentClass2, ...]):
     'Optional class documentation string'
     class_suite

 class Parent:  # 定义父类
    parentAttr = 100

    def __init__(self):
        print "调用父类构造函数"

    def parentMethod(self):
        print '调用父类方法'

    def setAttr(self, attr):
        Parent.parentAttr = attr

    def getAttr(self):
        print "父类属性 :", Parent.parentAttr


 class Child(Parent):  # 定义子类
    def __init__(self):
       print "调用子类构造方法"

    def childMethod(self):
       print '调用子类方法'

c = Child()  # 实例化子类
c.childMethod()  # 调用子类的方法
c.parentMethod()  # 调用父类方法
c.setAttr(200)  # 再次调用父类的方法 - 设置属性值
c.getAttr()  # 再次调用父类的方法 - 获取属性值

六、多继承

class P1(object):
    def foo(self):
        print 'p1-foo'

class P2(object):
    def foo(self):
        print 'p2-foo'

def bar(self):
    print 'p2-bar'

class C1(P1, P2):
    pass

class C2(P1, P2):
     def bar(self):
         print 'C2-bar'

class D(C1, C2):
     pass

对经典类和新式类来说,属性的查找顺序是不同的。现在我们分别看一下经典类和新式类两种不同的表现
1、经典类

d = D()
d.foo() # 输出 p1-foo
d.bar() # 输出 p2-bar
实例d调用foo()
时,搜索顺序是
D = > C1 = > P1
实例d调用bar()
时,搜索顺序是
D = > C1 = > P1 = > P2
换句话说,经典类的搜索方式是按照“从左至右,深度优先”的方式去查找属性。d先查找自身是否有foo方法,没有则查找最近的父类C1里是否有该方法,如果没有则继续向上查找,直到在P1中找到该方法,查找结束。
2、新式类
使用新式类要去掉第一段代码中的注释

d = D()
d.foo() # 输出 p1-foo
d.bar() # 输出 c2-bar
实例d调用foo()
时,搜索顺序是
D = > C1 = > C2 = > P1
实例d调用bar()
时,搜索顺序是
D = > C1 = > C2
可以看出,新式类的搜索方式是采用“广度优先”的方式去查找属性。

可以调用类的mro属性来查看查找顺序

七、方法重写
class Parent: # 定义父类
def myMethod(self):
print '调用父类方法'

class Child(Parent):  # 定义子类
    def myMethod(self):
        print '调用子类方法'

c = Child()  # 子类实例
c.myMethod()  # 子类调用重写方法

单下划线、双下划线、头尾双下划线说明:
foo: 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,587评论 18 139
  • 写在之前 因为简书字数限制,完整版地址:https://www.zybuluo.com/hainingwyx/no...
    hainingwyx阅读 13,860评论 0 41
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,139评论 9 118
  • 笛声优雅你的微笑在幽谷里冉冉晕开远山,晨曦,薄雾Irish色彩 湖上清风摇曳亲爱的你在哪里欢快 午后有些倦怠等的人...
    刘小木阅读 125评论 0 0
  • 前一阵女友间聚会,不知怎地提起了初恋。众人一致要求我第一个坦白,并说坦白从严,抗拒更严。为不引起众怒,我只好投降。...
    小不稀阅读 381评论 0 4