python 对象和类
python中所有数据都是以对象形式存在。对象既包含数据(变量),也包含代码(函数),是某一类具体事物的特殊实例。
面向对象的三大特性为封装、继承和多态。
1、定义类
#定义空类
class Person():
pass
#添加对象初始化方法
def Person():
def __init__(self):
pass
self参数指向正在被创建的对象本身。
self 代表的是类的实例,代表当前对象的地址,而 self.__class__ 则指向类。
#初始化方法中添加参数
def Person():
def __init__(self,name):
self.name=name
2、创建实例
>>>hunter=Person('Elmer Fudd')
上一行做了以下工作:
- 查看Person类的定义
- 在内存中实例化(创建)一个新的对象调用对象的__init__方法,将这个新创建的对象作为self传入,并将另一个参数‘Elmer Fudd’作为name传入
- 将name的值存入对象
- 返回这个新的对象
- 将名字hunter和这个对象关联
3、访问属性
使用点号 . 来访问对象的属性
print(hunter.name)
一些内置类属性:
- __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
- __doc__ :类的文档字符串
- __name__: 类名
- __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
- __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
4、继承
继承即从已有类中衍生出新的类,可以添加或修改部分功能。便于代码复用。
class Car():
pass
class Yugo(Car):
pass
5、类方法覆盖
新创建的子类会自动继承父类的所有信息。
class Car():
def exclaim(self):
print("I'm a Car!")
class Yugo(Car):
pass
t1=Car()
t2=Yugo()
>>>t1.exclaim()
I'm a Car!
>>>t2.exclaim()
I'm a Car!
对继承的方法进行修改后会覆盖原有的方法。
class Car():
def exclaim(self):
print("I'm a Car!")
class Yugo(Car):
def exclaim(self):
print("I'm a Yugo!")
t1=Car()
t2=Yugo()
>>>t1.exclaim()
I'm a Car!
>>>t2.exclaim()
I'm a Yugo!
在子类中,可以覆盖父类的方法,包括__init__()方法
class MDPerson(Person):
def __init__(self,name):
self.name="Doctor" + name
a=Person('Tom')
b=MDPerson('Tom')
>>>a.name
Tom
>>>b.name
Doctor Tom
6、子类添加新方法
class Car():
def exclaim(self):
print("I'm a Car!")
class Yugo(Car):
def exclaim(self):
print("I'm a Yugo!")
def push(self):
print('need a push')
a=Car()
b=Yugo()
>>>b.push()
need a push
7、使用super()调用父类方法
class EPerson(Person):
def __init__(self,name,email):
super().__init__(name)
self.email=email
我们应当使用super()来让父类完成其应当做的事情。并且,如果父类的定义以后发生改变,使用super()可以保证这些改变会自动反映到子类上,而不需要手动修改。
8、self参数作用
以下句代码举例:
>>>t1.exclaim()
- 查找t1对象所属的类Car
- 把t1对象作为self参数传给Car类所包含的exclaim()方法
相当于:
>>>Car.exclaim(t1)
9、使用property属性访问
property(fget,fset,fdel,doc)
class Duck():
def __init__(self,iname):
self.hidden_name=iname
def get_name(self):
return self.hidden_name
def set_name(self,iname):
self.hidden_name=iname
name=property(get_name,set_name)
最后一行将get_name,set_name定义为name属性。当访问name时,get_name()会被自动调用。当对name执行赋值操作时,set_name()方法会被调用。
tt=Duck('Howard')
>>>tt.name
'Howard'
>>>tt.name='Tom'
>>>tt.name
'Tom'
也可以通过装饰器方式定义property。
- @property,用于指定getter方法
- @name.setter,用于指定setter方法
class Duck():
def __init__(self,iname):
self.hidden_name=iname
@property
def name(self):
return self.hidden_name
@name.setter
def name(self,iname):
self.hidden_name=iname
property除指向类中存储的某一属性(如hidden_name),也可以指向计算结果值。
class Circle():
def __init__(self,radius):
self.radius=radius
@property
def diameter(self):
return 2*self.radius
c=Circle(5)
>>>c.radius
5
>>>c.diameter
10
>>>c.radius=7
>>>c.diameter
14
如果没有指定property的setter,将无法从类的外部对它的值进行设置。
与直接访问属性相比,如果改变某一属性的定义,只需要在类定义中修改代码,不需要在每一处调用修改。
10、使用__保护私有属性
把hidden_name改为__name:
class Duck():
def __init__(self,iname):
self.__name=iname
@property
def name(self):
return self.__name
@name.setter
def name(self,iname):
self.__name=iname
ff=Duck('Tom')
>>>ff.name
'Tom'
>>>ff.name='Do'
>>>ff.name
'Do'
此时name能够正常使用,但是如果试图使用ff.__name则会报错,无法从外部直接访问。
但是这种方法没有本质上将其变为私有,只是将其名称重整,通过以下方法仍可从外部访问:
>>>ff._Duck__name
'Do'
11、方法类型
- 以self作为第一个参数的方法都是实例方法
- 类方法则作用于整个类,对类作出的任何改变都会对它的所有实例对象产生影响。用装饰器@classmethod指定。类方法第一个参数为类本身,写作cls
- 静态方法用@staticmethod修饰,不需要self参数和cls参数。出现在类的定义中只是为了方便
12、多态与鸭子类型(duck typing)
python对多态要求宽松,可以对不同对象调用同名方法,甚至不用管对象的类型。
多态:
class Quote():
def __init__(self,person,words):
self.person=person
self.words=words
def who(self):
return self.person
def says(self):
return self.words+'.'
class Question(Quote):
def says(self):
return self.words+'?'
class Exclamation(Quote):
def says(self):
return self.words+'!'
t1=Quote('Tom','doc')
t2=Question('BB','doc')
t3=Exclamation('JJ','doc')
>>>print(t1.who(),'says:',t1.says())
Tom says: doc.
>>>print(t2.who(),'says:',t2.says())
BB says: doc?
>>>print(t3.who(),'says:',t3.says())
JJ says: doc!
鸭子类型:
class Brook():
def who(self):
return 'Brook'
def says(self):
return 'Babble'
brook=Brook()
def who_says(obj):
print(obj.who(),'says:',obj.says())
>>>who_says(t1)
Tom says: doc.
>>>who_says(t2)
BB says: doc?
>>>who_says(t3)
JJ says: doc!
>>>who_says(brook)
Brook says: Babble
13、特殊方法:__
建立一个普通的判断字符串相等的类:
class Word():
def __init__(self,text):
self.text=text
def equals(self,word2):
rreturn self.text.lower()==word2.text.lower()
first=Word('ha')
second=Word('HA')
third=Word('eh')
>>>first.equals(second)
True
>>>first.equals(third)
False
如果通过first==second判断是不是更加简洁?现在把方法equals()改为__eq__():
class Word():
def __init__(self,text):
self.text=text
def __eq__(self,word2):
rreturn self.text.lower()==word2.text.lower()
first=Word('ha')
second=Word('HA')
third=Word('eh')
>>>first==second
True
>>>first==third
False
相当于重载运算符==.
- __eq__(self,other) self==other
- __ne__(self,other) self!=other
- __lt__(self,other) self<other
- __gt__(self,other) self>other
- __le__(self,other) self<=other
- __ge__(self,other) self>=other
- __add__(self,other) self+other
- __sub__(self,other) self-other
- __mul__(self,other) self * other
- __floordiv__(self,other) self // other
- __truediv__(self,other) self / other
- __mod__(self,other) self % other
- __pow__(self,other) self ** other
- __str__(self) str(self)
- __repr__(self) repr(self)
- __len__(self) len(self)
- __init__() 根据类的定义以及传入的参数对新创建的对象进行初始化
14、类组合
class A():
def __init__(self,des):
self.des=des
class B():
def __init__(self,des):
self.des=des
class C():
def __init__(self,a,b):
self.a=a
self.b=b
def about(self):
print('A:',self.a.des,',B: ',self.b.des)
t1=A('a')
t2=B('b')
t3=C(t1,t2)
>>>t3.about()
A: a ,B: b
15、何时使用类
- 需要许多具有相似行为但不同状态的实例时,使用类和对象
- 类支持继承,模块不支持
- 如果想要保证实例的唯一性,使用模块
- 如果有一系列包含多个值的变量,并且能作为参数传入不同的函数,最好封装到类
- 用最简单的方法解决问题。使用字典、列表、元组等比使用模块更加简单。使用类更加复杂
python 对象和类的更多相关文章
- Python对象和类
Python 里的所有数据都是以对象形式存在的,对象是类的实例. 定义类(class) 使用class来定义一个类. 比如,定义一个cat类,如下: class Cat(): def __init__ ...
- Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理
上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...
- 对于python,一切事物都是对象,对象基于类创建
新建列表.新建string字符串 li1 = [1, 2, 3, 4] li2 = list([1, 2, 3]) s1 = "abc" s2 = str("abc&qu ...
- 从0开始的Python学习012数据结构&对象与类
简介 数据结构是处理数据的结构,或者说,他们是用来存储一组相关数据的. 在Python中三种内建的数据结构--列表.元组和字典.学会了使用它们会使编程变得的简单. 列表 list是处理一组有序的数据结 ...
- python的类和对象(类的静态字段)
转自:http://www.cnblogs.com/Eva-J/p/5044411.html 什么是静态字段 在开始之前,先上图,解释一下什么是类的静态字段(我有的时候会叫它类的静态变量,总之说的都是 ...
- Python里的类和对象简介
---恢复内容开始--- Python里的类 对象=属性+方法: 对象的属性主要是指主要的特征和参量,而方法主要是指函数: 类是一个具有一定特征和方法的集合,而对象是类的一个:类和对象的关系就如同模 ...
- Python面试题之Python对象反射、类反射、模块反射
python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 一.getattr 对象获取 class Manager: role = &quo ...
- python入门17 类和对象
类:一类事物的抽象化.概念: 类的变量(属于类的变量,定义在类的开始处) 成员变量(self.变量) 类的方法( @classmethod,cls参数) 成员方法( self参数 ) 静态方法 ...
- Python之面向对象类和对象
Python之面向对象类和对象 定义一个类:class 定义类的语法: class Test(object): """ 类里定义一类事物共同的技能. 可以是变量,也可是函 ...
随机推荐
- Python 使用标准库根据进程名获取进程PID
应用场景 在进行 Linux 运维的环境中,我们经常会遇到维护同一台服务器上的多个程序,涉及到程序的启动.关闭和重启操作. 通常这些程序之间存在着相互依存的关系需要进行依次的启动关闭操作. 下面介绍几 ...
- 第二百一十四节,jQuery EasyUI,Calendar(日历)组件
jQuery EasyUI,Calendar(日历)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Canlendar(日历)组件的使用方法 ...
- 8148 add spi driver
http://blog.csdn.net/zouwen198317/article/details/8452209 http://e2e.ti.com/support/dsp/davinci_digi ...
- uva414 - Machined Surfaces
uva414 - Machined Surfaces /* 水题,值得一提的是,getline使用时注意不能让它多吃回车键,处理方法可以用getchar. */ #include <iostre ...
- ASP.NET Web API 2中的属性路由(Attribute Routing)
如何启用属性路由并描述属性路由的各种选项? Why Attribute Routing? Web API的第一个版本使用基于约定的路由.在这种类型的路由中,您可以定义一个或多个路由模板,这些模板基本上 ...
- 机器学习框架MXnet安装步骤
安装环境:redhat7.1+vmw 安装步骤: # Install git if not already installed. sudo yum -y install git-all# Clone ...
- Codeforces Round #372 (Div. 1) B. Complete The Graph
题目链接:传送门 题目大意:给你一副无向图,边有权值,初始权值>=0,若权值==0,则需要把它变为一个正整数(不超过1e18),现在问你有没有一种方法, 使图中的边权值都变为正整数的时候,从 S ...
- label 两次点击 事件冒泡 使用时间戳的解决方案
情况描述:在页面中input 和 label 通过for banding 然后点击input 或者label的时候都要执行一个方法 但是在点击label的时候有两次执行两次的情况,及监听到的cli ...
- A day
今天推荐一部微电影,从老人的视角看这个社会. 老人在途中买橘子的经历仿佛是看到了当年自己的影子. A day对于有些人来说,很长.对于某些人来说很短暂.这一天所做的事情就是穿过马路走过天桥去水果店买四 ...
- centos6.5上搭建gitlab服务器(亲测可用哦)
最近的版本控制中,git可谓是脱缰的野马,一发不可收拾.当然git的设计模式也是愈发的成熟,让人刮目相看,完美解决了svn上的不足之处.在目前分布式横行的天下,git可谓是占得了一席之地. 废话少说, ...