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开发基础 作业:开发一个 ...
随机推荐
- javascript打乱数组顺序-----1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js获取手机重力感应api
<html> <head> <title>DeviceOrientationEvent</title> <meta charset="U ...
- Mongodb数据库命令端经常使用操作
数据库基本命令操作 数据库经常使用命令 1.Help查看命令提示 help db.help(); db.yourColl.help(); db.youColl.find().help(); rs.he ...
- SQL Server索引进阶:第十三级,插入,更新,删除
在第十级到十二级中,我们看了索引的内部结构,以及改变结构造成的影响.在本文中,继续查看Insert,update,delete和merge造成的影响.首先,我们单独看一下这四个命令. 插入INSERT ...
- JavaScript之<noscript>标签简介
早期浏览器都面临一个特殊的问题,即当浏览器不支持JavaScript时如何让页面平稳的退化.对这个问题的终极方案就是创造一个<noscript>元素,用以在不支持或支持但禁用了JavaSc ...
- Object-c的一些基本概念
自学了一个多月的IOS,对Object-C也有了初步的认识,也有很多观点不知道是否正确,所以整理了一下,和小伙伴们分享分享 1.OC中使用的消息机制代替调用方法 区别:使用消息结构的语言,其运行时缩引 ...
- ##DAY10 UITableView基础
##DAY10 UITableView基础 UITableView继承于UIScrollView,可以滚动. UITableView的每⼀条数据对应的单元格叫做Cell,是UITableViewCel ...
- Java随机数生成原理--转稿
1.Math库里的static(静态)方法random() 该方法的作用是产生0到1之间(包括0,但不包括1)的一个double值. double rand = Math.random(); 2.通过 ...
- leetcode two sum python
class Solution: # @param {integer[]} nums # @param {integer} target # @return {integer[]} def twoSum ...
- Linux学习之chage命令
功能:修改帐号和密码的有效期限用法:chage[-l][-m mindays][-M maxdays][-I inactive][-E expiredate][-W warndays][-d last ...