Python学习--10 面向对象编程
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
本节对于面向对象的概念不做展开说明。本节主要内容是Python里如何使用面向对象编程。
分下面几部分:
1、类的格式
2、类的实例
3、类的封装
4、继承和多态
类的格式
下面是一个示例:
student.py
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))
通过例子可以发现:
1、类由class
开头,类名首字母大写,类名后面的括号表示继承自基类object
,所有类都会继承这个类;
2、类的构造方法是__init__
,第一个参数是固定的,永远是self
,类里面通过self
调用属性和方法,不同于JAVA里使用this
。
现在来实例化类:
stu = Student('yjc', 22)
print(stu)
print(stu.name)
stu.print_score()
输出:
<__main__.Student object at 0x028811F0>
yjc
yjc: 22
Python里实例化类不用new
关键字,而是像使用函数那样即可。调用类里的方法的时候不用传self
参数。
类的封装
默认的,我们实例化了类后,可以直接访问对象里的属性,也可以去修改对象里的属性:
stu = Student('yjc', 22)
print(stu.name)
stu.print_score()
stu.name = 'Allen'
stu.print_score()
输出:
yjc
yjc: 22
Allen: 22
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__
,在Python中,实例的变量名如果以__
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问(子类里也不能继承),所以,我们把Student类改一改:
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))
stu = Student('yjc', 22)
print(stu.name)
输出:
Traceback (most recent call last):
File "/Projects/python/code/class/Student.py", line 12, in <module>
print(stu.__name)
AttributeError: 'Student' object has no attribute '__name'
这时候如果直接访问,就会报错。
继承和多态
在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类
(Subclass),而被继承的class称为基类
、父类
或超类
(Base class、Super class)。
继承示例:
class Animal(object):
def run(self):
print('runing')
class Dog(Animal):
pass
以上Dog
类继承了Animal
类,从而获得父类的方法run()
:
dog = Dog()
dog.run()
输出:
runing
这里子类虽然没有写run()
方法,但由于父类已经拥有,所以可以直接继承过来。
需要注意的是父类的私有变量(__
开头的)子类是不能访问,也不能继承的。
再看看类的多态:
class Dog(Animal):
def run(self):
print('Dog is runing')
class Cat(Animal):
def run(self):
print('Cat is runing')
def runClass(obj):
obj.run()
runClass(Animal())
runClass(Dog())
runClass(Cat())
输出:
runing
Dog is runing
Cat is runing
通过例子我们可以看到:
1、子类如果定义了和父类一样的方法,子类的会覆盖父类;
2、方法runClass
接收一个Animal
类,只要含有run()
方法,均可正常运行,原因就在于多态。
类属性和实例属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性。对于上面的Animal
类,我们可以动态绑定新的属性:
a = Animal()
a.name = 'lala'
但这个绑定的属性属于实例,不属于类,其它Animal
的实例是不能访问的。
在类里直接定义的属性,称为类属性,所有实例均可访问。
获取对象信息
type
最简单的,我们可以使用type()
获取对象的类型:
>>> type(1)
<class 'int'>
>>> type('1')
<class 'str'>
>>> type(True)
<class 'bool'>
>>> type(1.2)
<class 'float'>
>>> type(None)
<class 'NoneType'>
>>> type(abs)
<class 'builtin_function_or_method'>
>>> type(lambda x:x*2)
<class 'function'>
>>> type([1,2])
<class 'list'>
>>> type((1,2))
<class 'tuple'>
>>> type({"name":"yjc"})
<class 'dict'>
>>> type((x for x in range(10)))
<class 'generator'>
还可以使用types
模块进行判断:
>>> import types
>>> def f():pass
...
>>>
>>> type(f)==types.FunctionType
True
>>> type(f)==types.BuiltinFunctionType
False
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
isinstance
对于类的继承关系,使用isinstance()
会更方便:
class Animal(object):
def run(self):
print('runing')
class Dog(Animal):
pass
dog = Dog()
isinstance(dog, Dog)
isinstance(dog,object)
dir
如果要获得一个对象的所有属性和方法,可以使用dir()
函数:
>>> import math
>>> dir(math)
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isfinite', 'isinf','isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'pi', 'pow', 'radians', 'sin','sinh', 'sqrt', 'tan', 'tanh', 'trunc']
类似__xxx__
的属性和方法在Python中都是有特殊用途的,比如__len__
方法返回长度。
getattr/setattr/hasattr
getattr()
可以获取类的某个属性,setattr()
可以设置类的某个属性,getattr()
可以判断类是否拥有某个属性:
class Animal(object):
def __init__(self):
self.type = 'animal'
self.area = 'China'
def run(self):
print('runing')
class Dog(Animal):
pass
dog = Dog()
print(hasattr(dog,'type'))
print(hasattr(dog,'run'))
print(hasattr(dog,'name'))
print(getattr(dog,'area'))
# print(getattr(dog,'name'))
setattr(dog, 'name', 'Aia')
print(getattr(dog,'name'))
输出:
True
True
False
China
Aia
使用getattr()
尝试获取对象的一个不存在属性会报错。可以通过设置默认值避免:
print(getattr(dog,'city', 'beijing')) #beijing
Python学习--10 面向对象编程的更多相关文章
- Python学习之==>面向对象编程(二)
一.类的特殊成员 我们在Python学习之==>面向对象编程(一)中已经介绍过了构造方法和析构方法,构造方法是在实例化时自动执行的方法,而析构方法是在实例被销毁的时候被执行,Python类成员中 ...
- 从0开始的Python学习014面向对象编程
简介 到目前为止,我们的编程都是根据数据的函数和语句块来设计的,面向过程的编程.还有一种我们将数据和功能结合起来使用对象的形式,使用它里面的数据和方法这种方法叫做面向对象的编程. 类和对象是面向对象 ...
- Python学习之==>面向对象编程(一)
一.面向对象与面向过程 面向对象与面向过程是两种不同的编程范式,范式指的是按照什么方式去编程.去实现一个功能.不同的编程范式本质上代表对各种不同类型的任务采取不同的解决问题的思路. 1.面向过程编程 ...
- Python开发——10.面向对象编程进阶
一.isinstance(obj,cls)和issubclass(sub,super) 1.isinstance(obj,cls) 判断obj是不是由cls产生的类 2.issubclass(sub, ...
- python学习_数据处理编程实例(二)
在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...
- Python:笔记(3)——面向对象编程
Python:笔记(3)——面向对象编程 类和面向对象编程 1.类的创建 说明:和Java不同的是,我们不需要显示的说明类的字段属性,并且可以在后面动态的添加. 2.构造函数 构造函数的功能毋庸置疑, ...
- Python学习day40-并发编程(终)
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- Python学习day39-并发编程(各种锁)
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- Python学习day38-并发编程(线程)
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
随机推荐
- Linux的文件夹配置
学习linux我个人认为首先须要了解清楚在系统中没给目录的详细事干什么的才行,这样在以后的学习其中以及在使用linux系统的过程中才会事半功倍. /bin 主要内容是系统的运行文件,可是/bin中的运 ...
- 再谈ORACLE CPROCD进程
罗列一下有关oprocd的知识点 oprocd是oracle在rac中引入用来fencing io的 在unix系统下,假设我们没有採用oracle之外的第三方集群软件,才会存在oprocd进程 在l ...
- VS SQL 出现%CommonDir%dte80a.olb 该解决方案
VS SQL 出现%CommonDir%dte80a.olb 该解决方案 在网上搜索解决方法的时候.别人就说你从别的电脑复制一个到C:\Program Files\Common Files\mic ...
- 【转】Android 系统菜单与自定义菜单
Android 系统菜单与自定义菜单实现方法如下:系统菜单显示DefaultMenu.java package com.wxz.menu; import com.wxz.menu.R; import ...
- 解决Xcode升级7.0后,部分.a静态库在iOS9.0的模拟器上,link失败的问题
简单描述一下这个问题:我们项目中使用了Google大神开发的LevelDB键值对数据库,在Xcode6,iOS8的环境下,编译好的.a静态库是可以正常使用的.但是升级后,发现在模拟器上无法link成功 ...
- 2014.first[未填]
之后就按照自己的直觉,整理了第一套,难度为简单,差不多比2013noipday1水一点...先练练手而已 T1 vijos1196吃糖果游戏 博弈论 依题意,我们可知,如果去分数目为2,3,7,8必输 ...
- poj1183 反正切函数的应用(水)
这一题主要是推导过程+注意一下范围. // 由公式4你可以得到: arctan(/a)=arctan[(/b+/c)/(-/b*c)] =>b*c-=a(b+c); 令 b=a+m,c=a+n; ...
- c#中的对象
字段,属性,方法 对象初始化过程 如果没有继承,顺序如下: 静态变量 静态构造函数 非静态变量 非静态构造函数 如果类有基类,那么基类和子类的初始化顺序如下: 继承类静态成员变量初始化 ...
- POJ 2337 输出欧拉路径
太无语了. 这道题做了一整天. 主要还是我太弱了. 以后这个就当输出欧拉路径的模版吧. 题目中的输出字典序最小我有点搞不清楚,看了别人是这么写的.但是我发现我过不了后面DISCUSS里面的数据. 题意 ...
- Competitive