一文掌握Python面向对象

Python是一种面向对象编程的语言,Python中几乎都是对象,简单数值类型,代码模块,可以说是万物皆对象。例如对于一个数值对象:

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:961562169

>>> type(1)
<class 'int'>
>>> dir(1)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

 

目录

  • 一、面向对象编程
  • 二、类和对象
  • 1.什么是类和对象2.自定义类:创建与调用3.属性、函数和方法4.类命名空间
  • 三、继承
  • 1.继承2.继承查询3.多个超类
  • 四、多态
  • 1.什么是多态2.开闭原则3.鸭子类型
  • 五、封装
  • 1.私有变量2.读写方法

 

一、面向对象编程

面向对象编程的思想将对象作为程序的基本单元,对象=数据(属性)+一套访问和操作这些数据的方法。就像在引言中说的,Python中所有的数据类型都可以被视为对象我们也可以自定义对象,即面向对象中类的概念。
从面向过程的编程到面向对象的编程,从语句到函数到类,抽象程度不断变高,但是更符合我们日常中的概念。
以学生成绩表为例,语句表达:

std1 = { 'name': 'Michael', 'score': 98 }
std2 = { 'name': 'Bob', 'score': 81 }

通过函数打印:

def print_score(std):
    print('%s: %s' % (std['name'], std['score']))

将对象数据:学生成绩,对数据处理的方法:打印,整合在一起就是一个类。

class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print('%s: %s' % (self.name, self.score))

给对象发消息实际上就是调用对象对应的关联函数,即对象的方法:

bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
bart.print_score()
lisa.print_score()

面向对象编程的好处主要有三个方面:
1)多态:可对不同类型的对象执行相同的操作。
2)封装:对外部隐藏有关对象工作原理的细节。
3)继承:可基于通用类创建出专用类。

二、类和对象

1.什么是类和对象

类是一种对象的统称,每个对象都属于特定的类,对象是类的实例,是Python中程序的基本单元,要创建对象,就首先要创建一个类。
通过赋值语句可以给对象赋予名称,名称可以有很多个但是id只有一个。

a = complex(1,1)

2.自定义类:创建与调用

1)class语句和类的初始化

class <类名>:
  def _init_(self,<参数表>):
  def <方法名>(self,<参数表>):

_init_()是一个特殊的函数名,用于根据类的定义创建实例对象,第一个参数必须是self。
2)调用类和方法

obj = <类名>(<参数表>)
obj.<方法>()

类方法中的self就是obj对象实例本身

#在Python中约定,类名大写字母开头,函数小写字母开头
class Person: 
 def set_name(self, name): 
 self.name = name 
 def get_name(self): 
 return self.name 
 def greet(self): 
 print("Hello, world! I'm {}.".format(self.name))

>>> foo = Person() #先创建Person(),再将foo名称与之关联
>>> bar = Person() 
>>> foo.set_name('Luke Skywalker') 
>>> bar.set_name('Anakin Skywalker') 
>>> foo.greet() 
Hello, world! I'm Luke Skywalker. 
>>> bar.greet() 
Hello, world! I'm Anakin Skywalker.

3.属性、函数和方法

方法和函数的区别表现在参数self上,方法中的第一个参数关联到它所属的实例,调用的时候无需这个参数,可以在类的外部将方法关联到一个普通的函数,通过这种方法,也可以实现普通函数对类中self实例的访问。

>>> class Class: 
... def method(self): 
... print('I have a self!') 
... 
>>> def function(): 
... print("I don't...") 
... 
>>> instance = Class() 
>>> instance.method() I have a self! 
>>> instance.method = function 
>>> instance.method() I don't...
>>> class Bird: 
... song = 'Squaawk!' 
... def sing(self): 
... print(self.song) 
... 
>>> bird = Bird() 
>>> bird.sing() 
Squaawk! 
>>> birdsong = bird.sing 
>>> birdsong() 
Squaawk!

4.类命名空间

在class语句中定义的代码都是在一个特殊的命名空间(类的命名空间)内执行的,而类的所有成员都可访问这个命名空间,例如:

class MemberCounter: 
 members = 0 
 def init(self): 
 MemberCounter.members += 1 
>>> m1 = MemberCounter() 
>>> m1.init() 
>>> MemberCounter.members 
1 
>>> m2 = MemberCounter() 
>>> m2.init() 
>>> MemberCounter.members 
2

如果给实例中的属性members赋值,那么该值将被写入m1的一个属性中,这个属性遮住了类级变量。m1中的属性将被覆盖为定值(类似于外部传递进来的实参值覆盖类命名空间内的全局变量),类中的操作不在影响该变量,但m1中的方法仍会影响其他实例中的该属性(类级变量)。

>>> class MemberCounter:
	members = 0
	def init(self):
		MemberCounter.members += 1
>>> m1 = MemberCounter()
>>> m1.init()
>>> m1.members
1
>>> m1.members=3
>>> m1.members
3
>>> m2= MemberCounter()
>>> m2.init()
>>> m2.members
2
>>> m1.init()
>>> m1.members
3
>>> m2.members
3
>>> m2.init()
>>> m2.members
4

三、继承

1.继承

1)定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
例如:Dog类和Cat类都继承自Animal类。

class Animal(object):
    def run(self):
        print('Animal is running...')
class Dog(Animal):
    pass

class Cat(Animal):
    pass

2)通过这种方法,子类可以获得父类全部的属性和方法,并可以新增,或者重写已有的方法。

class Filter: 
  def init(self): 
  self.blocked = [] 
  def filter(self, sequence): 
  return [x for x in sequence if x not in self.blocked] 
class SPAMFilter(Filter): # SPAMFilter是Filter的子类
  def init(self): # 重写超类Filter的方法init 
  self.blocked = ['SPAM']
>>> f = Filter() 
>>> f.init() 
>>> f.filter([1, 2, 3]) 
[1, 2, 3]
>>> s = SPAMFilter() 
>>> s.init() 
>>> s.filter(['SPAM', 'SPAM', 'SPAM', 'SPAM', 'eggs', 'bacon', 'SPAM']) 
['eggs', 'bacon']

2.继承查询

1)要确定一个类是否是另一个类的子类,可使用内置方法issubclass:

>>> issubclass(SPAMFilter, Filter) 
True 
>>> issubclass(Filter, SPAMFilter) 
False

2)查询基类,可访问其特殊属性 __bases__;查询对象属于哪个类,可使用属性__class__:

>>> SPAMFilter.__bases__ 
(<class __main__.Filter at 0x171e40>,) 
>>> Filter.__bases__ 
(<class 'object'>,)

3)确定对象是否是特定类的实例,可使用isinstance:

>>> s = SPAMFilter() 
>>> isinstance(s, SPAMFilter) 
True 
>>> isinstance(s, Filter)
True

3.多个超类

1)多重继承,继承多个父类的属性和方法:

class Calculator: 
 def calculate(self, expression): 
 self.value = eval(expression) 
class Talker: 
 def talk(self): 
 print('Hi, my value is', self.value) 
class TalkingCalculator(Calculator, Talker): 
 pass
>>> tc = TalkingCalculator() 
>>> tc.calculate('1 + 2 * 3') 
>>> tc.talk() 
Hi, my value is 7

2)注意:如果多个超类以不同的方式实现了同一个方法(同名方法),必须在class语句中小心排列这些超类,因为位于前面的类的方法将覆盖位于后面的类的方法。因此,在前面的示例中,如果Calculator类包含方法talk,那么这个方法将覆盖Talker
类的方法talk(导致它不可访问)。

四、多态

1.什么是多态

我们首先要对数据类型再作一点说明。当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样,子类对象的数据类型是子类本身,同时也是父类的数据类型
多态的用法例如,定义一个函数:

def run_twice(animal):
    animal.run()
    animal.run()
>>> run_twice(Animal())
Animal is running...
Animal is running...

>>> run_twice(Dog())
Dog is running...
Dog is running...

>>> run_twice(Cat())
Cat is running...
Cat is running..

2.开闭原则

多态的好处就是,由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思。调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:
1)对扩展开放:允许新增Animal子类;
2)对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

3.鸭子类型

一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了,实际上对于Python,就是针对函数中调用的方法,只要有,不管定义的类型是什么,传递进去的类型是什么,都可以:

>>> def runtwice(anywithrun):
	anywithrun.run()
	anywithrun.run()

五、封装

在Class内部,可以有属性和方法,而外部代码可以通过直接 调用实例变量的方法(读写) 来操作数据,这样,就隐藏了内部的复杂逻辑。

1.私有变量

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))
>>> bart = Student('Bart Simpson', 59)
>>> bart.__name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'

注意:①如果变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以尽量避免使用这种变量。
②如果变量名以一个下划线开头,这样的实例变量外部是可以访问的,但是,意思就是,请当作私有变量不要随意访问。
③即使是private变量,Python也提供了访问的方法,因为Python解释器对外把__xxx变量改成了_类名__xxx,所有通过下面这种方式也可以访问,但是尽量不要这样做。

>>> bart._Student__name
'Bart Simpson'

2.读写方法

例如上面的例子,如果外部代码要获取name和score,可以给Student类增加get_name和get_score这样的方法,如果要允许外部代码修改score,可以再给Student类增加set_score方法:

class Student(object):
    ...

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score
        
    def set_score(self, score):
        self.__score = score 

 

Python面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它将数据和操作封装在对象中,通过对象之间的交互实现程序的设计和开发。下面是一些关键概念,帮助你更好地理解Python面向对象编程。 1. (Class):是对象的蓝图或模板,描述了对象的属性和行为。它定义了对象的特征和方法。例如,我们可以定义一个名为"Car"的来表示汽车,其中包含属性(如颜色、型号)和方法(如加速、刹车)。 2. 对象(Object):对象是的实例,是具体的实体。通过实例化,我们可以创建一个对象。例如,我们可以创建一个名为"my_car"的对象,它是基于"Car"的实例。 3. 属性(Attribute):属性是对象的特征,用于描述对象的状态。每个对象都可以具有一组属性。例如,"Car"的属性可以包括颜色、型号等。 4. 方法(Method):方法是对象的行为,用于定义对象的操作。每个对象都可以具有一组方法。例如,"Car"的方法可以包括加速、刹车等。 5. 继承(Inheritance):继承是一种机制,允许我们创建一个新(称为子),从现有(称为父)继承属性和方法。子可以扩展或修改父的功能。继承可以实现代码重用和层次化设计。 6. 多态(Polymorphism):多态是一种特性,允许不同的对象对同一方法做出不同的响应。多态提高了代码的灵活性和可扩展性。 7. 封装(Encapsulation):封装是一种将数据和操作封装在对象中的机制,隐藏了对象的内部实现细节,只暴露必要的接口给外部使用。这样可以保护数据的安全性,提供了更好的模块化和代码复用性。 通过理解这些概念,你可以更好地掌握Python面向对象编程。在实践中,你可以使用来创建对象,操作对象的属性和调用对象的方法,通过继承和多态实现代码的灵活性和可扩展性,通过封装保护数据的安全性和提高代码的可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值