A Byte of Python 笔记(9) 面向对象编程
第11章 面向对象编程
面向过程:根据操作数据的函数或语句块来设计程序。
面向对象(OOP, object-oriented programming):把数据和功能结合起来,用对象包裹组织程序。
类是用来描述具有相同属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。
类和对象是面向对象编程的两个主要方面。类创建一个新类型,而对象是类的 实例。
类似于你有一个 int 类型的变量,存储整数的变量是 int 类的实例(对象)。
注意,即便是整数也被作为对象(属于int类)。这和C++、Java(1.5版之前)把整数纯粹作为类型是不同的。通过 help(int) 了解更多这个类的详情。 C#和Java 1.5程序员会熟悉这个概念,因为它类似于 封装与解封装 的概念。 |
类的属性有域和方法。域即类的变量,可以存储数据;方法即类的函数,具有某种功能。
域有两种类型——属于每个实例/类的对象或属于类本身,它们分别被称为实例变量和类变量。
类使用 class 关键字创建,类的域和方法被列在一个缩进块中。
self
类的方法与普通函数有一个特别的区别,类方法必须有一个额外的第一个参数名称 self(这个变量指向对象本身),调用时无需为该参数赋值,python 会提供这个值。如果你有一个不需要参数的方法,也需要给这个方法定义一个 self 参数。
Python中的 self 等价于C++中的 self 指针和 Java、C#中的 this 参考。 |
self 的原理:类 MyClass 的实例 MyObject,调用对象的方法 MyObject.method(arg1, arg2)时,python 会自动转为 MyClass.method(MyObject, arg1, arg2)。
# -*- coding: utf-8 -*-
# Filename: simplestclass.py class Person:
pass p = Person()
print p
使用 class 语句后跟类名创建一个新类,类体为一个空白块,由 pass 语句表示。
创建一个对象/实例:使用类名后跟一对圆括号。打印的是存储对象的计算机内存地址。
对象的方法
类/对象可以拥有像函数一样的方法,这些方法与函数的区别只是一个额外的 self 变量。
# -*- coding: utf-8 -*-
# Filename: method.py class Person:
def sayHi(self):
print 'Hello, how are you?' p = Person()
p.sayHi() # This short example can also be written as person().sayHi()
Person().sayHi()
sayHi 方法没有任何参数,但仍然在函数定义时有 self。
__init__() 方法
__init__() 方法是一种特殊的方法,称为类的构造函数或初始化方法,当类的对象/实例创建时就会调用,用来对对象做一些初始化。
注意:__init__ 的开始和结尾都是双下划线。
# -*- coding: utf-8 -*-
# Filename: class_init.py class Person:
def __init__(self, name):
self.name = name
def sayHi(self):
print 'Hello, my name is', self.name p = Person('Swaroop')
p.sayHi() # This short example can also be written as Person('Swaroop').sayHi()
Person('Swaroop').sayHi()
__init__ 方法定义为取一个参数 name(以及普通的参数self)。__init__创建了一个新的域,称为 name。
最重要的是,我们没有专门调用 __init__ 方法,只是在创建一个类的新实例的时候,把参数包括在圆括号内跟在类名后面,从而传递给 __init__ 方法。这是这种方法的重要之处。
__init__ 方法类似于C++、C# 和 Java 中的 constructor 。 |
类与对象的方法
数据是与类和对象的名称空间 绑定 的普通变量,即这些名称只在这些类与对象的前提下有效。
有两种类型的 域——类的变量和对象的变量,它们根据是类还是对象 拥有 这个变量而区分。
类的变量 由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,当某个对象对类的变量做改动时,这个改动会反映到所有其他的实例上。
对象的变量 由类的每个对象/实例拥有。每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是互不相关的。
# -*- coding: utf-8 -*-
# Filename: objvar.py class Person:
'''Represents a person.'''
population = 0 def __init__(self, name):
'''Initializes the person's data.'''
self.name = name
print '(Initializeing %s.)' % self.name # When this person is created, he/she adds to the population
Person.population += 1 def __del__(self):
'''I am dying.'''
print '%s says bye.' % self.name
Person.population -= 1 if Person.population == 0:
print 'I am the last one.'
else:
print 'There are still %d people left.' % Person.population def sayHi(self):
'''Greeting by the person.
Really, that's all it does.'''
print 'Hi, my name is %s.' % self.name def howMany(self):
'''Prints the current population.'''
if Person.population == 1:
print 'I am the only person here.'
else:
print 'We have %d persons here.' % Person.population swaroop = Person('Swaroop')
swaroop.sayHi()
swaroop.howMany() kalam = Person('Abdul Kalam')
kalam.sayHi()
kalam.howMany() swaroop.sayHi()
swaroop.howMany()
本例说明了类与对象的变量的本质。population 属于 Person 类,是类的变量;name 变量属于对象(使用 self 赋值),是对象的变量。
两个特殊方法 __init__ 和 __del__ :
(1)__init__() 方法 被称为类的构造函数,用来初始化 Person 实例。self.name 的值根据每个对象指定,表明了它作为对象的变量的本质。
记住,只能使用 self 变量来参考同一个对象的变量和方法,称为 属性参考。
(2)__del__() 方法 被称为类的析构函数,在对象消逝时被调用。对象消逝即对象不再被使用,它所占用的内存将返还给系统。当对象不再使用时, __del__ 方法运行,如果很难保证究竟在 什么时候 运行。用户可以指明它的运行,使用 del 语句。
类的文档字符串可以通过 ClassName.__doc__ 查看:
运行时使用 Person.__doc__ 和 Person.sayHi.__doc__ 分别访问类与方法的文档字符串。
给C++/Java/C#程序员的注释 Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。 只有一个例外:如果你使用的数据成员名称以 双下划线前缀 比如 __privatevar,Python的名称管理体系会有效地把它作为私有变量。 这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。 而其他的名称都将作为公共的,可以被其他类/对象使用。 记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。 同样,注意__del__方法与 destructor 的概念类似。 |
Python对象销毁(垃圾回收)
1. 同Java语言一样,Python使用了引用计数这一简单技术来追踪内存中的对象。
2. 垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。
上述实例中如执行:del u1,则u1对象被销毁,打印:User destroyed
Python 内置类属性
__doc__ 类的文档字符串
__name__ 类名
__module__ 类定义所在的模块(类的全名是 '__main__.className',如果类位于一个导入模块 mymod 中,那么 className.__module__=mymod)
__bases__ 类的所有父类构成元素(包含了一个由所有父类组成的元组)
__dict__ 类的属性(包含一个字典,由类的数据属性组成)
继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过 继承 机制。继承完全可以理解成类之间的 类型和子类型 关系。
1、声明类的时候括号中写要继承的父类
2、类的继承衍生出子类,子类可以继承或重写父类的方法,子类可以自定义新的方法或成员变量。
例:教师和学生有共同属性,也有专有属性。可以创建一个共同的类 SchoolMember ,让教师和学生的类 继承 这个类,即它们都是这个类型(类)的子类型,然后再为这些子类型添加专有的属性。
向 SchoolMember 中增加/改变任何功能,会自动反映到子类型中。在子类型中做改动不会影响到别的子类型。子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作父类的实例,这种现象被称为多态现象。
SchoolMember 称为 基本类 或 超类;Teacher 和 Student 类被称为 导出类 或 子类。
# -*- coding: utf-8 -*-
# Filename: inherit.py class SchoolMember:
'''Represents any school member'''
def __init__(self,name,age):
self.name = name
self.age = age
print '(Initialized SchoolMember: %s)' % self.name def tell(self):
'''Tell my details.'''
print 'Name:"%s" Age:"%s"' % (self.name, self.age), class Teacher(SchoolMember):
'''Represents a teacher.'''
def __init__(self,name,age,salary):
SchoolMember.__init__(self,name,age)
self.salary = salary
print '(Initialized Teacher: %s)' % self.name def tell(self):
SchoolMember.tell(self)
print 'Salary:"%d"' % self.salary class Student(SchoolMember):
'''Represents a student.'''
def __init__(self,name,age,marks):
SchoolMember.__init__(self,name,age)
self.marks = marks
print '(Initialized a Student: %s)' % self.name def tell(self):
SchoolMember.tell(self)
print 'Marks:"%d"' % self.marks t = Teacher('Mrs. Shriry',40,30000)
s = Student('Tom',22,75) print # prints a blank line members = [t,s]
for member in members:
member.tell() # works for both Teacher and Student
为了使用继承,我们把基本类的名称作为一个元组跟在定义类时类名称之后。
基本类的 __init__ 方法专门用 self 变量调用,可以初始化对象的基本类部分
——python 不会自动调用基本类的 constructor,必须专门调用。
在方法调用之前加上类名称前缀,然后把 self 变量及其他参数传递给它。
python 首先查找对应类型的方法,如果不能在导出类中找到对应的方法,才开始到基本类中逐个查找。
基本类在类定义的时候,在元组中指明。如果在继承元组中列出了一个以上的类,称为 多重继承。
Python类私有属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。
在类内部的方法中使用时self.__private_attrs。
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。
在类的内部调用self.__private_methods
Python实例方法、类方法、静态方法
实例方法,类方法,静态方法都可以通过实例或者类调用,只不过实例方法通过类调用时需要传递实例的引用(python 3可以传递任意对象,其他版本会报错)
实例方法针对的是实例,第一个参数是self,普通对象方法至少需要一个self参数,代表类对象实例;
类方法针对的是类,@classmethod 它表示接下来的是一个类方法,类方法的第一个参数cls,它们都可以继承和重新定义;
静态方法用于作为程序中的共享资源,直接通过类去调用,不用实例化对象,不需要self参数,可以认为是全局函数,@staticmethod 它表示接下来的是一个静态方法
A Byte of Python 笔记(9) 面向对象编程的更多相关文章
- Python:笔记(3)——面向对象编程
Python:笔记(3)——面向对象编程 类和面向对象编程 1.类的创建 说明:和Java不同的是,我们不需要显示的说明类的字段属性,并且可以在后面动态的添加. 2.构造函数 构造函数的功能毋庸置疑, ...
- 8.python笔记之面向对象基础
title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...
- Python学习之==>面向对象编程(二)
一.类的特殊成员 我们在Python学习之==>面向对象编程(一)中已经介绍过了构造方法和析构方法,构造方法是在实例化时自动执行的方法,而析构方法是在实例被销毁的时候被执行,Python类成员中 ...
- Python 中的面向对象编程
面向对象编程(Object-oriented programming, OOP)是一种基于对象概念的编程范式,可包含属性(attribute)形式的数据以及方法(method)形式的代码.另一种对 O ...
- python 学习笔记7 面向对象编程
一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." ...
- python学习笔记(七):面向对象编程、类
一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...
- python自动化测试学习笔记-7面向对象编程,类,继承,实例变量,邮件
面向对象编程(OOP)术语: class TestClass(object): val1 = 100 def __init__(self): self.val2 = 200 ...
- python中的面向对象编程
在python中几乎可以完成C++里所有面向对象编程的元素. 继承:python支持多继承: class Derived(base1, base2, base3): pass 多态:python中的所 ...
- Day7 - Python基础7 面向对象编程进阶
Python之路,Day7 - 面向对象编程进阶 本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个 ...
随机推荐
- 整理Linux查看系统日志的一些经常使用命令
整理Linux查看系统日志的一些经常使用命令 last -a 把从何处登入系统的主机名称或ip地址,显示在最后一行. -d 指定记录文件.指定记录文件.将IP地址转换成主机名称. -f <记录文 ...
- OpenGL绘制简单场景,实现旋转缩放平移和灯光效果
本项目实现了用OpenGL绘制一个简单场景,包括正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码.有具体凝视.适合刚開始学习的人熟悉opengl使用. 开发情况 开发环境V ...
- [转载]VMWare网络连接透析
http://blog.csdn.net/struggleyb/article/details/1102214 以前在学校,VMWare里面的Gentoo Linux是采用network bridge ...
- 一个JAVA代码
public class HelloJava { public static void main(String[] args) { System.out.println("这"); ...
- BZOJ 3566: [SHOI2014]概率充电器( 树形dp )
通过一次dfs求出dp(x)表示节点x考虑了x和x的子树都没成功充电的概率, dp(x) = (1-p[x])π(1 - (1-dp[son])*P(edge(x, son)).然后再dfs一次考虑节 ...
- python读取中文文件编码问题
python 读取中文文件后,作为参数使用,经常会遇到乱码或者报错asii错误等. 我们需要对中文进行decode('gbk') 如我有一个data.txt文件有如下内容: 百度 谷歌 现在想读取文件 ...
- eclipse run on server 浏览器启动设置
- python学习【一】基础入门
Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...
- HTML5速查表
HTML5速查表 标签 描述 版本 属性 <!--...--> 定义注释 4 / 5 none <!DOCTYPE> 定义文档类型 4 / 5 none <a> 定 ...
- docker10件事
docker – 你应该知道的10件事 容器并不是一个全新的技术,但这并不妨碍Docker如风暴一样席卷整个世界. 如果你在IT圈里,你一定听说过Docker.就算与其他热门技术,如:Puppet ...