Python面向对象编程基础实例分析

 更新时间:2020年01月17日 08:59:06   作者:theVicTory  
这篇文章主要介绍了Python面向对象编程基础,结合实例形式分析了Python面向对象编程类的定义、继承、特殊方法及模块相关原理与操作技巧,需要的朋友可以参考下

本文实例讲述了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制作简易注册登录系统

    Python制作简易注册登录系统

    这篇文章主要为大家详细介绍了Python简易注册登录系统的制作方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】

    Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】

    这篇文章主要介绍了Python数据结构与算法之链表定义与用法,结合具体实例形式较为详细的分析了单链表、循环链表等的定义、使用方法与相关注意事项,需要的朋友可以参考下
    2017-09-09
  • python简单商城购物车实例代码

    python简单商城购物车实例代码

    这篇文章主要为大家详细介绍了python简单商城购物车的实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • 详解Python中的文本处理

    详解Python中的文本处理

    这篇文章主要介绍了Python中的文本处理,包括从最基本的string模块的基础使用和更进一步的re模块的使用,本文来自IBM官方开发者技术文档,需要的朋友可以参考下
    2015-04-04
  • python回调函数用法实例分析

    python回调函数用法实例分析

    这篇文章主要介绍了python回调函数用法,较为详细的分析了常用的调用方式,并实例介绍了Python回调函数的使用技巧,需要的朋友可以参考下
    2015-05-05
  • python3格式化字符串 f-string的高级用法(推荐)

    python3格式化字符串 f-string的高级用法(推荐)

    从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快!本文重点给大家介绍python3格式化字符串 f-string的高级用法,一起看看吧
    2020-03-03
  • 详解Python 数据库 (sqlite3)应用

    详解Python 数据库 (sqlite3)应用

    本篇文章主要介绍了Python标准库14 数据库 (sqlite3),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧。
    2016-12-12
  • 用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)

    用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)

    这篇文章主要介绍了用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • Python中__str__()方法的实用技巧分享

    Python中__str__()方法的实用技巧分享

    在Python编程中,__str__()是一个特殊方法,它允许自定义对象的字符串表示形式,本文将深入探讨__str__()的相关实用技巧,希望对大家有所帮助
    2023-11-11
  • Python使用Paramiko控制linux第三方库

    Python使用Paramiko控制linux第三方库

    这篇文章主要介绍了Python使用Paramiko控制linux第三方库,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05

最新评论