Python 面对对象编程

面向对象编程:

  • 面向过程:根据业务逻辑从上到下写垒代码
  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。

封装

封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

继承

面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”。

被继承的类称为“基类”、“父类”或“超类”。

继承的过程,就是从一般到特殊的过程。

要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。

在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

继承概念的实现方式主要有2类:实现继承、接口继承。

?         实现继承是指使用基类的属性和方法而无需额外编码的能力;

?         接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法);

在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。

抽象类仅定义将由子类创建的一般属性和方法。

OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。

多态

多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

Pyhon 很多语法都是支持多态的,比如 len(),sorted(), 你给len传字符串就返回字符串的长度,传列表就返回列表长度。

面向对象高级语法部分

经典类vs新式类

把下面代码用python2 和python3都执行一下

#_*_coding:utf-8_*_
class A:
    def __init__(self):
        self.n = ‘A‘
class B(A):
    # def __init__(self):
    #     self.n = ‘B‘
    pass
class C(A):
    def __init__(self):
        self.n = ‘C‘
class D(B,C):
    # def __init__(self):
    #     self.n = ‘D‘
    pass
obj = D()
print(obj.n)

classical vs new style:

  • 经典类:深度优先
  • 新式类:广度优先
  • super()用法  

静态方法

通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法

class people(object):
    def __init__(self,name):
        self.name = name
    @staticmethod
    def eat(self):
        print("%s is eating ...."%self.name)
a = people("xiao")
a.eat()

上面的调用会出以下错误,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。

想让上面的代码可以正常工作有两种办法

1. 调用时主动传递实例本身给eat方法,即d.eat(a)

2. 在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了

class people(object):
    def __init__(self,name):
        self.name = name
    @staticmethod
    def eat():
        print(" is eating ....")
a = people("xiao")
a.eat()

 类方法  

类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

class people(object):
    def __init__(self,name):
        self.name = name
    @classmethod
    def eat(self):
        print("%s is eating ...."%self.name)
a = people("xiao")
a.eat()

执行报错,说Dog没有name属性,因为name是个实例变量,类方法是不能访问实例变量的

此时可以定义一个类变量,也叫name,看下执行效果

class people(object):
    name = "类变量"
    def __init__(self,name):
        self.name = name
    @classmethod
    def eat(self):
        print("%s is eating ...."%self.name)
a = people("xiao")
a.eat()

属性方法  

属性方法的作用就是通过@property把一个方法变成一个静态属性

class people(object):
    name = "类变量"
    def __init__(self,name):
        self.name = name
    @property
    def eat(self):
        print("%s is eating ...."%self.name)
a = people("xiao")
a.eat()

调用会出错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接d.eat就可以了

正常调用如下

a = people("xiao")
a.eat

类的特殊成员方法

1. __doc__  表示类的描述信息

class Foo(object):
    """描述信息"""
    def __init__(self):
        self.name = ‘alex‘

    def func(self):
        print("is ok")
        #return ‘func‘
obj = Foo()
print(obj.__doc__)输出:描述信息

2. __module__ 和  __class__ 

  __module__ 表示当前操作的对象在那个模块

  __class__     表示当前操作的对象的类是什么

class C(object):
    def __init__(self):
        self.name = "name"
from lib.abc import C
obj = C()
print(obj.__module__)
print(obj.__class__)输出:lib.abc<class ‘lib.abc.C‘>

3. __init__ 构造方法,通过类创建对象时,自动触发执行。

4.__del__

 析构方法,当对象在内存中被释放时,自动触发执行。

 注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的

5. __call__ 对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class a(object):
    def __init__(self):
        pass
    def __call__(self, *args, **kwargs):
        print(args[0])
obj = a()
obj(1)
输出:
1

6. __dict__ 查看类或对象中的所有成员   

class people(object):
    def __init__(self):
        self.name = "alex"
        self.age = 45
obj = people()
print(obj.__dict__)
输出:
{‘name‘: ‘alex‘, ‘age‘: 45}

7.__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

class people(object):
    def __init__(self):
        self.name = "alex"
        self.age = 45
    def __str__(self):
        return self.name
obj = people()
print(obj)
输出:
alex

8.__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

反射

通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

class Foo(object):
    def __init__(self):
        self.name = ‘alex‘

    def func(self):
        print("is ok")
        #return ‘func‘
obj = Foo()
#### 检查是否含有成员 ####
print(hasattr(obj, ‘name‘))
print(hasattr(obj, ‘func‘))

#### 获取成员 ####
print(getattr(obj, ‘name‘))
getattr(obj, ‘func‘)()

#### 设置成员 ####
setattr(obj, ‘age‘, 18)
setattr(obj, ‘show‘, lambda num: num + 1)
print(getattr(obj,"show")(1))

#### 删除成员 ####
delattr(obj, ‘name‘)
delattr(obj, ‘func‘)输出:TrueTruealexis ok2

动态导入模块

import importlib

__import__(‘import_lib.metaclass‘) #这是解释器自己内部用的
#importlib.import_module(‘import_lib.metaclass‘) #与上面这句效果一样,官方建议用这个
时间: 2024-10-08 15:57:03

Python 面对对象编程的相关文章

python面对对象编程-------5:获取属性

一:最基本的属性操作 1 class Generic: 2 pass 3 4 g= Generic() 5 6 >>> g.attribute= "value" #创建属性并赋值 7 >>> g.attribute 8 'value' 9 >>> g.unset 10 Traceback (most recent call last): 11 File "<stdin>", line 1, in &l

python面对对象编程

基本概念 class类 一个类即是对一类拥有相同属性的对象的抽象.蓝图.原型.在类中定义了这些对象的都具备的属性(variables(data)).共同的方法 Object 对象 一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同 Encapsulation 封装在类中对数据的赋值.内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的

python接口自动化九--面对对象编程二,搭建测试环境,多线程与多进程

1.面对对象编程 1.1 基本概念 实例方法:在类里面定义的函数都是实例方法,函数内有self变量 类方法: 不可以实例化,直接用类名调用 类方法可以使用类变量,cls.xxx 实例可以通过self.xx使用类方法 类方法里面不能使用实例方法和实例变量 静态方法: 定义在类里的普通函数 用不了实例方法,实例变量,类方法,类变量 不需要实例化,直接用类名调用 ? 属性方法: 是实例方法 不能有入参 用它的时候,直接m.func,把它当做变量来使用,后面不需要加括号 它是获取函数的返回值 析构函数:

Python - 面对对象(其他相关,异常处理,反射,单例模式,等..)

目录 Python - 面对对象(其他相关,异常处理,反射,等..) 一.isinstance(obj, cls) 二.issubclass(sub, super) 三.异常处理 1. 异常处理 2.异常种类 3.异常其他结构 4.主动触发异常 5.自定义异常 6.断言 四.反射 五. 单例模式 Python - 面对对象(其他相关,异常处理,反射,等..) 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 class Foo(object): pass ob

Python - 面对对象(基础)

目录 Python - 面对对象(基础) 一. 概述 二. 创建类和对象 三. 面向对象三大特征 封装 继承 多态 Python - 面对对象(基础) 一. 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." 面向过程编程(Object Oriented Programming,OOP,面向对象程序设计) 最易被初学者接受,其往往用一长段代码来实现指定功能,开发

16、python面对对象之类和继承

前言:本文主要介绍python面对对象中的类和继承,包括类方法.静态方法.只读属性.继承等. 一.类方法 1.类方法定义 使用装饰器@classmethod装饰,且第一个参数必须是当前类对象,该参数名一般约定为“cls",通过它来传递类的属性和方法 (不能传递实例属性和实例方法),跟实例方法的self用法相似. 2.类方法的调用 实例对象和类对象都可以调用 3.应用场景 在需要站在类的角度执行某个行为时,那么就可以定义为类方法 class Student: def __init__(self,

跟着百度学PHP[4]OOP面对对象编程-7-OOP的一些关键子讲解

面对对象常用的一些关键子:http://www.cnblogs.com/xishaonian/p/6146794.html排版不是很好望见谅. THE END 跟着百度学PHP[4]OOP面对对象编程-7-OOP的一些关键子讲解

跟着百度学PHP[4]OOP面对对象编程-5-内部引用$this

$this就是对象内部代表这个对象的引用 可以调用被封装的方法或者属性! <?php class Person{ private $name; private $age="21"; var $sex; function play(){ echo "他正在玩儿呢"; } private function Hello(){ //使用private封装hello方法.该方法不可直接调用.但是可以在内部使用$this调用. echo "这个是被封装的内容&q

js面对对象编程

说到js,很大一部分人会说我很熟悉,在日常的web开发中经常用,那么你的js代码是符合面对对象思路的吗?那你会问我面向过程的js代码有什么不好吗?我的感受是面对对象的js编码更加简洁,减少了混乱,可维护行增强,适合编写富客户端时应用. 好了,首先看看js里如何定义对象: <html> <head> <script type="text/javascript"> var obj=new Object(); obj.name='josh'; obj.ag