python的对象和方法_python 对象和类

python中所有数据都是以对象形式存在。对象既包含数据(变量),也包含代码(函数),是某一类具体事物的特殊实例。

面向对象的三大特性为封装、继承和多态。

1、定义类

#定义空类

classPerson():pass

#添加对象初始化方法

defPerson():def __init__(self):pass

self参数指向正在被创建的对象本身。

self 代表的是类的实例,代表当前对象的地址,而 self.__class__ 则指向类。

#初始化方法中添加参数

defPerson():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、继承

继承即从已有类中衍生出新的类,可以添加或修改部分功能。便于代码复用。

classCar():pass

classYugo(Car):pass

5、类方法覆盖

新创建的子类会自动继承父类的所有信息。

classCar():defexclaim(self):print("I'm a Car!")classYugo(Car):passt1=Car()

t2=Yugo()>>>t1.exclaim()

I'm a Car!

>>>t2.exclaim()

I'm a Car!

对继承的方法进行修改后会覆盖原有的方法。

classCar():defexclaim(self):print("I'm a Car!")classYugo(Car):defexclaim(self):print("I'm a Yugo!")

t1=Car()

t2=Yugo()>>>t1.exclaim()

I'm a Car!

>>>t2.exclaim()

I'm a Yugo!

在子类中,可以覆盖父类的方法,包括__init__()方法

classMDPerson(Person):def __init__(self,name):

self.name="Doctor" +name

a=Person('Tom')

b=MDPerson('Tom')>>>a.name

Tom>>>b.name

Doctor Tom

6、子类添加新方法

classCar():defexclaim(self):print("I'm a Car!")classYugo(Car):defexclaim(self):print("I'm a Yugo!")defpush(self):print('need a push')

a=Car()

b=Yugo()>>>b.push()

need a push

7、使用super()调用父类方法

classEPerson(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)

classDuck():def __init__(self,iname):

self.hidden_name=inamedefget_name(self):returnself.hidden_namedefset_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方法

classDuck():def __init__(self,iname):

self.hidden_name=iname

@propertydefname(self):returnself.hidden_name

@name.setterdefname(self,iname):

self.hidden_name=iname

property除指向类中存储的某一属性(如hidden_name),也可以指向计算结果值。

classCircle():def __init__(self,radius):

self.radius=radius

@propertydefdiameter(self):return 2*self.radius

c=Circle(5)>>>c.radius5

>>>c.diameter10

>>>c.radius=7

>>>c.diameter14

如果没有指定property的setter,将无法从类的外部对它的值进行设置。

与直接访问属性相比,如果改变某一属性的定义,只需要在类定义中修改代码,不需要在每一处调用修改。

10、使用__保护私有属性

把hidden_name改为__name:

classDuck():def __init__(self,iname):

self.__name=iname

@propertydefname(self):return self.__name@name.setterdefname(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对多态要求宽松,可以对不同对象调用同名方法,甚至不用管对象的类型。

多态:

classQuote():def __init__(self,person,words):

self.person=person

self.words=wordsdefwho(self):returnself.persondefsays(self):return self.words+'.'

classQuestion(Quote):defsays(self):return self.words+'?'

classExclamation(Quote):defsays(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!

鸭子类型:

classBrook():defwho(self):return 'Brook'

defsays(self):return 'Babble'brook=Brook()defwho_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、特殊方法:__

建立一个普通的判断字符串相等的类:

classWord():def __init__(self,text):

self.text=textdefequals(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__():

classWord():def __init__(self,text):

self.text=textdef __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

__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、类组合

classA():def __init__(self,des):

self.des=desclassB():def __init__(self,des):

self.des=desclassC():def __init__(self,a,b):

self.a=a

self.b=bdefabout(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、何时使用类

需要许多具有相似行为但不同状态的实例时,使用类和对象

类支持继承,模块不支持

如果想要保证实例的唯一性,使用模块

如果有一系列包含多个值的变量,并且能作为参数传入不同的函数,最好封装到类

用最简单的方法解决问题。使用字典、列表、元组等比使用模块更加简单。使用类更加复杂

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值