本文实例讲述了Python面向对象编程基础。分享给大家供大家参考,具体如下:
1、类的定义
Python中类的定义与对象的初始化如下,python中所有类的父类是object,需要继承。
由于Python是动态语言,因此可以直接为对象添加属性并赋值而不必在类定义中声明
class Person(object): # 定义一个Person类 pass p = Person() # 初始化一个Person对象 p.name="xiaoming" # 对象属性赋值
Python的类初始化方法为__init__(),其第一个参数为self代之对象自身,其后为各个参数,初始化就是将传入的参数赋值给对象的属性。**kw代表任意数量的属性,通过key=attribute的形式传入,之后通过setattr()方法将每个属性赋值给对象。
直接在class中定义的变量称为类属性,在__init__()中定义的为对象属性,类属性供所有对象共享,对象只能访问却无权修改。当通过对象给类属性赋值时,会为对象新建一个同名的对象属性,而不是修改类属性。无论在类的内部还是外部,都通过类名对类属性进行访问。
以__开头的变量无法被外部访问,类似于私有变量。这时就需要对象的实例方法从类的内部访问私有变量并做出相应的操作,这样在类的内部定义的方法叫做实例方法,实例方法的第一个参数默认为self代表对象自己。
相应地类方法只能访问类属性,其定义方式是在之前添加标记@classmethod:,其第一个参数cls代表类本身
class Person(object): count = 0 # 类属性 @classmethod: def get_count(cls): # 类方法 return cls.count def __init__(self,name,gender,birth,**kw): Person.count+=1 # 访问类属性 self.name = name self.__gender = gender self.birth = birth for k, v in kw.iteritems(): # 遍历之后的键值对,设置属性 setattr(self, k, v) def get_name(self): # 定义实例方法 return self.__name xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student') xiaoming.count==9 # 为对象创建属性,不会修改Person.count print(xiaoming.job) # 显示Student print(xiaoming.__gender) # 无法访问,抛出异常AttributeError print(xiaoming.get_name()) # 通过实例方法访问内部变量
2、类的继承
Python中类的继承方式如下。值得注意的是在子类Teacher中需要通过super(子类名,self)调用父类的初始化函数来完成对父类中参数的初始化。也可以直接通过父类名称调用父类的方法
通过type()方法输出变量的类型,isinstance()可以判断变量是否是某个类型,dir()方法返回变量的所有属性和方法列表。输出对象t的属性结果如下,其中带__的为默认属性,其余为自定义的属性
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'course', 'gender', 'name']
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender class Teacher(Person): # 继承父类Person def __init__(self, name, gender, course): super(Teacher,self).__init__(name,gender) # 调用父类的初始化函数 self.course= course # 完成子类变量的初始化 t = Teacher('Alice', 'Female', 'English') print(isinstance(t,Person)) # 结果为True,子类也是父类的类型 print(dir(t)) # 显示对象的所有属性
和其他面向对象的语言一样,Python具有多态的特性,例如父类和不同的子类都定义了相同的方法,当不同的子类调用该方法时会调用自己定义的方法,从而实现相同的方法具有不同的操作。但python是动态语言,和静态语言C++、Java不同的是在调用实例方法时,python不检查类型,只要方法存在,参数正确,就可以调用。例如原本json的load方法中定义了read()方法用于实现对文件的读取,当我们自定义一个类其中包含read()方法时,便可动态调用实例方法
import json class Students(object): def read(self): return r'["Tim", "Bob", "Alice"]' s = Students() print json.load(s)
一个子类可以同时继承两个以上的父类,这个特性叫做多继承,当有多个父类时,需要在初始化时指明父类
class A(object): def __init__(self, a): self.a = a class B(object): def __init__(self, b): self.b = b class C(A, B): def __init__(self, a, b, c): A.__init__(self, a) B.__init__(self, b) self.c = c c = C(1, 2, 3) print(c.a) # 输出1
3、类的特殊方法
Python的特殊方法是指定义在类中,以__开头和结尾,由某些函数或操作符隐式触发调用的方法。例如当我们使用print(p)打印一个Person对象p时,就会调用Person的__str__()方法将p转化为字符串共print输出,输出结果为:<__main__.Person object at 0x000001787CC7C0D0>
当我们重新自定义这些特殊方法后,当触发调用时就会按我们定义的函数执行。例如重新定义__str__(),当print()时就会显示My name is Bob
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __str__(self): # 重新定义类特殊方法 return "My name is " + self.name p = Person('Bob', 'male') print(p) # 输出结果为:My name is Bob
__cmp__()方法用于实现类的比较,在排序时会自动调用。例如在Student类中重新定义该方法,按分数高低对学生进行排序,其有两个参数,第一个自己self,第二个是比较的对象s,如果self应该在s之前,则返回-1
class Student(object): def __init__(self, name, score): self.name = name self.score = score def __cmp__(self, s): # 重写__cmp__方法 if self.score>s.score: return -1 # self在s之前 elif self.score<s.score: return 1 else: return 0 L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 99)] Ls = sorted(L) # 使用sorted对Student类进行排序
__len__()方法用于返回长度,当len()调用类时会触发
__add__、__sub__、__mul__、__div__分别对应类的加减乘除运算,当类遇到运算符+-*/时会调用该方法,例如实现一个分数类Rational的加法:1/2+1/4,通分相加得6/8,最后求最大公约数后约分得到3/4
__int__、__float__方法在int()、float()调用类时触发,可以重新该方法返回一个int或float结果
def gcd(a, b): # 求最大公约数 if b == 0: return a return gcd(b, a % b) class Rational(object): def __init__(self, p, q): self.p = p self.q = q def __add__(self, r): # 重写加法运算 return Rational(self.p * r.q + self.q * r.p, self.q * r.q) def __str__(self): g = gcd(self.p, self.q) # 将分数约分后输出 return '%s/%s' % (self.p / g, self.q / g) def __float__(self): # 将分数转化为float小数返回 return float(self.p)/float(self.q) r1 = Rational(1, 2) r2 = Rational(1, 4) print(r1 + r2) # 两个类相加 print(float(r1)) # 输出小数形式
类属性的装饰器@property用于将类方法转化为属性,这样就可以像访问属性一样调用方法。例如Student类的__score属性对外是不可见的,通过定义返回方法score使得对象s可以通过s.score得到分数值。
@property.setter方法用于对属性设置方法进行装饰,使得可以像给属性赋值一样调用类方法。例如当使用s.score=99时会调用设置方法score(self,score),将值传递给__score,并且可以对传入值的合法性进行检验。
__slots__()用于定义类中可以使用的属性,父类定义过的子类中无需重复定义。当添加新的属性并赋值时,运行会抛出异常AttributeError
__call__()将一个类实例变成一个可调用对象,例如一个Student对象s,像函数调用一样使用对象:s('Alice')
class Student(object): __slots__ = ('name','__score') # 本类只允许使用name、score两个属性 def __init__(self, name, score): self.name = name self.__score = score @property # 定义属性返回方法 def score(self): return self.__score @score.setter # 定义属性设置方法 def score(self, score): if score < 0 or score > 100: raise ValueError('invalid score') self.__score = score def __call__(self, friend): print('My friend is %s...' % friend) s = Student('Bob', 59) s.score = 60 # 调用属性设置方法 print(s.score) # 调用属性返回方法 s.grade='A' # 抛出异常,无法添加其他属性 s('Alice') # 输出My friend is Alice...
__getattribute__(self,attr)、__setattr__(self,attr)、__delattr__(self,attr)分别用于获取、设置、删除属性时触发的方法,在使用时应注意避免递归调用引起的无限循环,例如在get方法中再调用get类似的方法导致无限循环。
4、模块管理
为了方便分类管理python中的类和方法,需要将代码放在不同的文件中,每个文件构成了一个独立的模块,不同模块之间相同的变量名不会引起命名冲突。但是如果在文件a.py中希望使用文件b.py中的函数func1,则可以通过import在a中导入模块b,并通过b.func1()调用该方法。或者通过from直接引入模块中的函数。在引入时为了防止命名冲突,可以通过as为引入的函数起个别名
# 文件a.py中 import b print(b.func1()) # 直接引入函数 from b import func1 print(func1()) # 使用别名 from b import func1 as f1 print(f1())
有时将相同类别的模块放在一个文件夹内,就形成了一个包,python要求一个包文件夹内必须有一个__init__.py文件才会识别为一个包,即使它是一个空文件。这时如果一个p1包内的a.py想访问p2包内的b.py中的函数func2,则操作如下
# p1/a.py文件内 import p2.b print (p2.b.func2())
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》
希望本文所述对大家Python程序设计有所帮助。
Python,面向对象编程
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 明达年度发烧碟MasterSuperiorAudiophile2021[DSF]
- 英文DJ 《致命的温柔》24K德国HD金碟DTS 2CD[WAV+分轨][1.7G]
- 张学友1997《不老的传说》宝丽金首版 [WAV+CUE][971M]
- 张韶涵2024 《不负韶华》开盘母带[低速原抓WAV+CUE][1.1G]
- lol全球总决赛lcs三号种子是谁 S14全球总决赛lcs三号种子队伍介绍
- lol全球总决赛lck三号种子是谁 S14全球总决赛lck三号种子队伍
- 群星.2005-三里屯音乐之男孩女孩的情人节【太合麦田】【WAV+CUE】
- 崔健.2005-给你一点颜色【东西音乐】【WAV+CUE】
- 南台湾小姑娘.1998-心爱,等一下【大旗】【WAV+CUE】
- 【新世纪】群星-美丽人生(CestLaVie)(6CD)[WAV+CUE]
- ProteanQuartet-Tempusomniavincit(2024)[24-WAV]
- SirEdwardElgarconductsElgar[FLAC+CUE]
- 田震《20世纪中华歌坛名人百集珍藏版》[WAV+CUE][1G]
- BEYOND《大地》24K金蝶限量编号[低速原抓WAV+CUE][986M]
- 陈奕迅《准备中 SACD》[日本限量版] [WAV+CUE][1.2G]