《Python⾼级编程》(六)类⼯⼚
类⼯⼚
定义
类⼯⼚本质:类⼯⼚就是⼀个在运⾏时创建类的函数。
即允许创建类时根据情况决定其属性,⽐如,根据⽤户输⼊创建属性。
类⼯⼚函数:是⼀个⽤于创建并返回类的函数
理解类⼯⼚函数
使⽤type创建类如下:
definit(lf,name):
=name
defeat(lf):
pass
defgo_to_vet(lf):
print"go_to_vet"
returntype('Animal',(object,),{
'__doc__':'Aclassreprentinganarbitraryanimal.',
'__init__':init,
'eat':eat,
'go_to_vet':go_to_vet,
})
这种⽅式的缺点:
这种写法会将函数置于和Animal同⼀层命名空间下。因此⼀般不使⽤type之间创建。
如果真需要使⽤type,则可以将其放⼊⼀个函数中,如下:
defcreate_animal_class():
definit(lf,name):
=name
defeat(lf):
pass
defgo_to_vet(lf):
print"go_to_vet"
returntype('Animal',(object,),{
'__doc__':'Aclassreprentinganarbitraryanimal.',
'__init__':init,
'eat':eat,
'go_to_vet':go_to_vet,
})
Animal=create_animal_class()
printAnima领导动员大会发言稿
l#
通过函数调⽤即可获得⼀个⾃定义创建的Animal类。
使⽤class关键字创建效果相同:
defcreate_animal_class():
classAnimal(object):
definit(lf,name):
=name
defeat(lf):
pass租房合同协议书
defgo_to_vet(lf):
print"go_to_vet军棋怎么下 "
returnAnimal
Animal=create_animal_class()
printAnimal#
何时编写类⼯⼚
在需要基于运⾏时的信息(如⽤电视当电脑显示器 户输⼊)创建类时需要编写类⼯⼚
如果在编码时并不知道需要赋值给类的属性时
类⼯⼚⽰例:(创建类⼯⼚的原因:假如说是为⼤量不同的第三⽅⽹站提供凭据的服务,则需要有多重不同的验证⽅式。该⼯⼚可
以根据数据库查询结果⽣成属性)
#-*-coding:utf-8-*-
defget_credential_class(u_proxy=Fal,tfa=Fal):
ifu_proxy:
keys=['rvice_name','email_address']#通过代理⾝份验证所要的密匙
el:
keys=['urname','password']
iftfa:
('tfa_token')
classCredential(object):
expected_keys=t(keys)
def__init__(lf,**kwargs):
ed_keys!=t(()):
raiValueError('Keysdonotmatch')
fork,():
tattr(lf,k,v)
returnCredential
cred=以不开头的成语 get_credential_class(0,0)
printcred
运⾏结果:
避免类属性⼀致性问题:处紫色代表 理类与实例之间属性不同的问题
类属性与实例属性
classC(object):
foo='bar'
classI(object):
def__init__(lf):
='bar梦见碗碎了 '
()
()#AttributeError
c1=C()
c2=C()
='baz'
#baz
#bar
='bacon'
#baz
#bacon
printc1.__dict__#{'foo':'baz'}
printc2.__dict__#{}
()#AttributeError原因:
foo作为C的⼀个实例被实例化,但并不作为I的属性被实例化。
由于直接访问I⽽不是I的实例,因此__init__函数还没有被允许。
⼀个对象的属性查找顺序遵循⾸先查找实例对象⾃⼰,然后是类,接着是类的⽗类。
本质:__dict__属性存储着对象的所有属性(和值)
注意:⼀些内置的数据类型是没有__dict__属性的:
int,list,dict等这些常⽤的数据类型是没有__dict__属性的,其实这是可预料的,就算给了它们dict属性也没啥⽤,毕竟它们只是⽤来做
数据容器的。
属性:指⼀个对象的数据或者函数
-属性的访问:通过句话(.)访问属性
-⽀持运⾏中添加和修改属性
字段:类的数据变量,例如:name='scolia'
⽅法:类⾥⾯的函数。可分为:
-实例⽅法:第⼀个参数需要是lf,它表⽰⼀个具体的实例本⾝。
-类⽅法:⽤classmethod,它的第⼀个参数不是lf,是cls,它表⽰这个类本⾝。类⽅法是那些并不需要类的实例就可以执⾏的⽅法
-静态⽅法:⽤staticmethod,可以⽆视lf,⽽将这个⽅法当成⼀个普通的函数使⽤
#-*-coding:utf-8-*-
classcls:
clsvar=1#普通字段
def__init__(lf):
=2
ins1=cls()
ins2=cls()
=20
#输出结果为1
#输出结果为20
#输出结果为1
#⽤类名为类变量重新赋值并打印
=10
#输出结果为10
#输出结果为20
#输出结果为10
#这次直接给实例1没有在类中定义的变量赋值
ins1.x=11
printins1.x#输出结果为11
#然后再⽤类名给类中没有定义的变量赋值
cls.m=21
printcls.m#输出结果为21
#再创建⼀个实例ins3,然后打印⼀下ins3的变量
ins3=cls()
#输出结果为2
#输出结果为10
printins3.m#输出结果为21
printins3.x#报错AttributeErro
类⽅法的限制
classC(object):
foo='bar'
@classmethod
defclassfoo(cls):
oo()#bacon
oo()#bacon
注意:类⽅法⽆法访问实例属性,它们并不需要⼀个实例,但需要类本⾝。
因此oo使⽤的是类的foo⽽不是实例c1的foo
使⽤类⼯⼚
使⽤时机:当你继承⼀个现有类并且所依赖的类属性必须调整时。
类⼯⼚是⽣成带有重载属性的恰当⼦类的⼀种恰当⽅式。
cla往岁 ssC(object):
foo='bar'
@classmethod
defclassfoo(cls):
defcreate_C_subclass(new_foo):
classSubC(C):
foo=new_foo
returnSubC
S=create_C_subclass('spam')
oo()#spam
E=create_C_subclass('eggs')
oo()#eggs
执⾏C⼦类的classfoo类⽅法创建类的⽅式返回需要的结果。
单例模式
让类⼯⼚函数难以使⽤的⼀点是类⼯⼚返回的是类⽽不是类的实例。
如果⼀个实例,则必须调⽤类⼯⼚函数返回的结果才可以。
单例模式是⼀种只允许⼀个实例的类模式。
类⼯⼚⽰例:
classC(object):
foo='bar'
@classmethod
defclassfoo(cls):
defCPrime(new_foo='bar'):
ifnew_foo=='bar':
returnC()
classSubC(C):
foo=new_foo
returnSubC
EE=CPrime('bar')
FF=CPrime('bar1')
printEE#<__main__.Cobjectat0x01777CB0>
printFF#
本文发布于:2023-03-26 20:00:31,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/1679832034399122.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:cprime.doc
本文 PDF 下载地址:cprime.pdf
留言与评论(共有 0 条评论) |