python面向对象编程 -- 基本概念(python3.5)

面向对象的编程简要概括就是将要处理的问题抽象为数据和操作的集合,用类对其进行封装。其中数据和操作都称为类的属性,它们是一般是不变的。

对类进行实例化生成我们所说的对象,对象有自己的属性。对象的属性一般是个性化的,不同的对象可能具有不同的属性。同一个类的所有对象都共享类的属性。

对象属性的查找顺序为:对象自身 --> 类 --> 类的祖先类

在python中一切皆对象。

以下我们讨论python中类相关的概念和语法。

1、类的定义

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>
  • 类定义必须使用class关键字
  • 类名最好使用大驼峰,如ClassName, 这是一种约定
  • 当输入类定义时,一个新的命名空间产生,在类中定义的所有本地变量都放入这个新的命名空间。
  • 命名空间中的所有变量都是类的属性。类属性主要分为两类,数据属性(变量)和函数。
  • 语句块执行完成后,生成一个类对象绑定到ClassName。ClassName的作用域由它的定义的位置决定。

python中一切皆对象,类也是对象,它是type类的实例。可以用 obj.__class__来查看一个对象是由那个类实例化而来的。

类中可以使用任何合法的语句,不过实际应用中,主要是赋值语句和函数定义。

2、类对象

下面的代码定义了一个 Chinese 类:

class Chinese:
    """A sample example class"""
    nationality = ‘China‘

    def display(self):
        print(self, ‘I am Chinese!‘, sep=‘, ‘)

for name, value in sorted(Chinese.__dict__.items(), key=lambda x: x[0]):
    print(name, ‘==>‘, value)

类定义会生成一个新的命名空间,其中包含了所有在类本地定义的变量,也就是类的属性。这些属性可以在类的 __dict__属性中查看,可以将其近似等价于类的命名空间。其中 __name__形式的属性为特殊属性。

print(type(Chinese.__dict__))   # <class ‘mappingproxy‘>
for name, value in sorted(Chinese.__dict__.items(), key=lambda x: x[0]):
    print(name, ‘==>‘, value)

# __dict__ ==> <attribute ‘__dict__‘ of ‘Chinese‘ objects>
# __doc__ ==> A sample example class
# __module__ ==> __main__
# __weakref__ ==> <attribute ‘__weakref__‘ of ‘Chinese‘ objects>
# display ==> <function Chinese.display at 0x1020759d8>
# nationality ==> China
  • __dict__  在类定义的时候自动生成。
  • __doc__  类定义的时候自动生成。值为类定义语句块内第一行,类的文档字符串,由三引号引用。如果没有值为None。
  • __module__ 类定义所在的模块,自动添加的属性。如果是正在执行的模块,值为 __main__
  • __weakref__
  • display 和 nationality 用户定义属性

python中属性的引用都是通过obj.name 的形式,name为对象 obj 的属性。类中的所有属性都可以通过obj.name 的形式引用。比如该类的两个用户自定义属性:数据属性 nationality 和 函数 display:

print(Chinese.nationality)  # China
print(Chinese.display)      # <function Chinese.display at 0x1021759d8>
Chinese.display(1)          # 1, I am Chinese!

通过类引用函数并对其进行调用,与普通的函数调用没有差异。不过,在类中定义的函数一般是给实例使用的,不建议直接通过类引用,下面会进一步说明。

3、类实例化

类的实例化使用和函数调用类似的语法。

xm = Chinese()

上面的语句创建了一个新的Chinese类的实例,并将其赋值给 xm 变量。实例有自己的命名空间:

print(xm.__dict__)  # {}

可以看到 xm.__dict__ 的返回值是一个空字典,实例 xm没有自己的属性。可以直接通过 xm.name = ‘xiaoming‘ 的形式为实例添加属性。也可以通过 del xm.name 删除该属性:

xm.name = ‘xiaoming‘
print(xm.__dict__)      # {‘name‘: ‘xiaoming‘}
del xm.name
print(xm.__dict__)      # {}

如果类的所有实例都具有某些属性,只是属性的值不同,可以通过定义实例的初始化方法,在方法中为实例添加属性。

3.1 初始化方法

类的实例化过程:

  1. 实例化出一个对象
  2. 自动调用特殊方法 __init__对产生的对象初始化。如果类中没有定义会在父类(父类的概念之后说明)中查找该方法。

我们称__init__方法为实例的初始化方法。

一般在实例初始化方法中会定义实例的个性化属性,这些属性是实例私有的,可以通过实例的__dict__属性查看。实例的属性不会影响类的属性,换句话说类不能引用实例的属性。

下面是对Chinese类的扩展:

class Chinese:
    """A sample example class"""
    nationality = ‘China‘

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def display(self):
        print(self, ‘I am Chinese!‘, sep=‘, ‘)

xm = Chinese(‘xiaoming‘, 18, ‘male‘)
print(xm.__dict__)      # {‘name‘: ‘xiaoming‘, ‘gender‘: ‘male‘, ‘age‘: 18}
print(Chinese.__dict__.keys())
# dict_keys([‘__weakref__‘, ‘__module__‘, ‘__dict__‘, ‘__init__‘, ‘nationality‘, ‘display‘, ‘__doc__‘])

self指代引用该方法的实例(具体实现在4.1介绍),实例化操作的参数列表化传递给__init__方法,Chinese(‘xiaoming‘, 18, ‘male‘) --> xm.__init__(‘xiaoming‘, 18, ‘male‘)

3.2 实例的类

查看对象的类:

  • obj.__class__
  • type(obj)
print(xm.__class__)
print(type(xm))
# <class ‘__main__.Chinese‘>
# <class ‘__main__.Chinese‘>

判断一个对象是不是某个类的实例:isinstance(obj, ClassName)

print(isinstance(xm, Chinese))
# True

4 实例

实例可以操作两种属性:数据属性和方法

print(xm.name, xm.age, xm.gender, sep=‘, ‘)   # xiaoming, 18, male
print(xm.nationality, xm.display, sep=‘, ‘)
# China, <bound method Chinese.display of <__main__.Chinese object at 0x10217c898>>

有上面的代码可以看到实例不仅可以引用自己的属性,也可以引用类的属性。类属性可以被它的实例共享。

值得注意的是,实例对类的函数的引用。其返回值并不是一个函数对象而是一个"bound method"绑定的方法对象。尝试调用这个对象:

1 xm.display(1)
2 # Traceback (most recent call last):
3 #   File "test.py", line 28, in <module>
4 #     xm.display(1)
5 # TypeError: display() takes 1 positional argument but 2 were given
6 xm.display()            # <__main__.Chinese object at 0x10217c7f0>, I am Chinese!

display函数要求传入一个位置参数,第1行给方法传入一个参数1,调用出错,错误信息告诉我们多传入了一个位置参数。

再次调用,不传参,竟然能够正常调用了!why?函数打印了传入的值,"<__main__.Chinese object at 0x10217c7f0>",表明出入的是一个Chinese对象,在本例中只能是 xm。这是怎么实现的呢?

4.1 实例方法

print(Chinese.display)
print(xm.display)
print(Chinese.display is xm.display)

# <function Chinese.display at 0x1021759d8>
# <bound method Chinese.display of <__main__.Chinese object at 0x10217c7f0>>
# False 

分别通过类和实例引用display属性,返回的并不是同一个对象:通过类引用返回一个函数对象;通过实例引用返回一个"bound method"绑定的方法对象。

  • 方法:属于某个对象的函数。当通过对象(实例)引用一个函数对象,函数和实例绑定返回一个方法对象。可以通过方法对象的__self__ 和 __func__ 属性查看对应的实例和方法

    method = xm.display
    print(method.__self__)      # <__main__.Chinese object at 0x10217c7f0>
    print(method.__func__)      # <function Chinese.display at 0x1021759d8> 
  • 方法对象是可调用的,方法的调用即其对应的函数调用,特殊之处在于会将其实例作为第一个参数传给函数,等价形式为:method(*args, **kwargs) ==> method.__func__(method.__self__, **args, **kwargs)。在本例中xm.display() 等价于Chinese.display(xm)。
  • 在类中定义的函数一般至少有一个位置参数,第一个位置参数一般用‘self‘标识,指代引用函数的实例。
  • 类中定义的函数对应到实例即为实例的方法。类中的函数一般都是通过实例引用的,为了便于描述下文中我们可能直接称类中的函数为方法。

简要概括来说就是,方法的第一个参数由python自动填充以引用实例对象。

以上是相关的基本概念,下一篇讨论类的封装、继承相关的概念。

时间: 2024-11-24 15:27:35

python面向对象编程 -- 基本概念(python3.5)的相关文章

(转)Python 面向对象编程(一)

Python 面向对象编程(一) 虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程.下面就来了解一下如何在Python中进行对象编程. 一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class className: block 注意类名后面有个冒号,在block块里面就可以定义属性和方法了.当一个类定义完之后,就产生了一个类对象.类对象支持

python 面向对象编程(一)

一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class className: block 注意类名后面有个冒号,在block块里面就可以定义属性和方法了.当一个类定义完之后,就产生了一个类对象.类对象支持两种操作:引用和实例化.引用操作是通过类对象去调用类中的属性或者方法,而实例化是产生出一个类对象的实例,称作实例对象.比如定义了一个people类: cl

python面向对象编程进阶

python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(object): 2 pass 3 4 obj = Foo() 5 6 isinstance(obj, Foo) issubclass(sub, super)检查sub类是否是 super 类的派生类 1 class Foo(object): 2 pass 3 4 class B

Python面向对象编程-封装

1引言 你点击了桌面上的Chrome图标,一个浏览器窗口出现了,输入网址就可以在Internet世界愉快玩耍.这一切是怎么实现的呢?Chromium这个多进程的程序是如何启动各个进程的呢?浏览器主进程(界面进程)启动了哪些线程?如何启动的呢?这些问题一直萦绕在心头,一起来看看源代码吧.本文主要针对Chromium for Mac的源代码,其它操作系统大同小异. 2背景知识 浏览器作为一个应用程序,是以进程的形式运行在操作系统上的.首先,Chromium是一个多进程的应用程序,我们需要了解Chro

Python面向对象编程总结(上)

在我学习python之前一直认为python是脚本型语言,不能用面相对象的方法进行编程,当我学习了python之后我发现我错了,python不但支持面相对象而且使用的人还挺多的.我从接触编程开始就是学习的Java语言,所以面相对象编程的思想在我的脑海里根深蒂固,让我一下从面向对象编程转换到面向过程编程还有一些不适应呢,所以我就来总结一下python面向对象编程的方法和过程.我将按照面向对象的构成要素来分析,依次为类和实例.属性.方法.封装.继承.多态,如果有什么问题还请大家积极指出,我所用的版本

二维数组 面向对象编程的概念、 类、对象以及引用 和成员方法

1.二维数组(熟悉)1.1 基本概念 一维数组本质上就是一段连续的存储单元,用于存放多个类型相同的数据内容. 二维数组本质上就是由多个一维数组组成的数组,也就是说二维数组中的每个元素都是一维数组,而一维数组的每个元素才是具体数据内容. 1.2 二维数组的声明(1)语法格式 数据类型[][] 数组名称 = new 数据类型[行数][列数];如: int[][] arr = new int[2][5]; - 声明一个具有2行5列元素类型为int的二维数组 其中行下标的范围是:0 ~ 1: 其中列下标

python面向对象编程(OOP)

python作为一种解释性语言,其主要的编程方式就是面向对象,而且python的框架django也是主要面向对象的编程. 类(class)和对象(object) 类(class)是用来描述具有相同属性(attribute)和方法(method)对象的集合.对象(object)是类(class)的实例.比如学生都有名字和分数,他们有着共同的属性.这时我们就可以设计一个学生类,用来记录学生的名字和分数,并自定义打印出来. 属性(attribute):类里面用于描述所有对象共同特征的变量或数据.比如此

Python面向对象编程指南(高清版)PDF

Python面向对象编程指南(高清版)PDF百度网盘链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网盘手机App,操作更方便哦内容简介 · · · · · · Python是一种面向对象.解释型的程序设计语言,它已经被成功应用于科学计算.数据分析以及游戏开发等诸多领域.本书深入介绍Python语言的面向对象特性,全书分3个部分共18章.第1部分讲述用特殊方法实现Python风格的类,分别介绍了init

Python面向对象编程——简介

Python面向对象编程--简介 编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 . 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式. 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路, 大多数语言只支持一种编程范式,当然也有些语言可以同时支持多种编程范式. 两种最重要的编程范式分别是面向