python子类继承父类属性实例_Python中父类和子类间类属性(非实例属性)的设置获取的传递...

前几天做一个项目,遇见类似这样一个问题。父类是个公用类,很多子项目中都运用到了,而子类也要作为一个基本类在该项目中的很多地方都要用到,但是的原始父类里面有些类属性(注意这里是类属性,不是实力属性)。在程序运行时候要进行重新设置。

背景:Python中父类的类属性,类方法,实力属性都能够被子类继承,实力属性的再设置很简单,当然为了控制类属性的访问权限(Python中不能完全实现控制),也可以用@preproty装饰符优化和控制实力属性的设置,父类的类属性被子类继承,可以很容易的获得父类属性的内容,但是如果想设置父类的类属性,就要用 父类名.类属性名 称来实现,那么能不能用 子类名.类属性名 来实现类属性的同步设置呢。

来看一个例子:class Grandfather(object):

mylist = []

def __init__(self):

pass

class Father(Grandfather):

def __init__(self):

pass

Grandfather.mylist = [1, 2, 3, 4]

print Grandfather.mylist

print Father.mylist

Father.mylist = [‘a‘]

print Grandfather.mylist

print Father.mylist

打印结果:[1, 2, 3, 4]

[1, 2, 3, 4]

[1, 2, 3, 4]

[‘a‘]

发现,如果使用Father.mylist = [‘a‘]

来实现类属性的设置,想象中,应该父类的类属性也能被重新设置,但是结果显示出,想象的和现实还是有差距的。

我也尝试了用@preproty和@xxx.setter等修饰符,单独以及配合@classmethod修饰符来实现用Father.mylist的实现类属性的同步设置,但结果都失败了。其实可以继续使用Grandfather的类名加类属性及Grandfather来实现父类属性的设置但是,就感觉明明有了新父类,模块中交替使用这两个类名来设置类属性,确实有点不是太完美。

后来经过尝试找到了一个新的方法,就是使用类元metaclass,至于metaclass的内容,大家可以在网上找到相应的文章,这里介绍两种使用方法。

第一种:class MetaMyList(type):

def _get_dummy(self):

return Grandfather.mylist

def _set_dummy(self, value):

Grandfather.mylist = value

mylist = property(_get_dummy, _set_dummy)

class Grandfather(object):

mylist = []

def __init__(self):

pass

class Father(Grandfather):

__metaclass__ = MetaMyList

def __init__(self):

pass

Grandfather.mylist = [1, 2, 3, 4]

print Grandfather.mylist

print Father.mylist

Father.mylist = [‘a‘]

print Grandfather.mylist

print Father.mylist

打印结果令人很满意:[1, 2, 3, 4]

[1, 2, 3, 4]

[‘a‘]

[‘a‘]

因为我们创建类的时候使用了__metaclass__, 那么类被创建的时候就会添加mylist作为自己的类属性,但是当我们使用Father.mylist来设置类属性的时候,我们其实是在将这个值传递给了Grandfather。因为Grandfather该类已经被创建,所以override该类属性的property是不现实(也许可以,但是我读书少)。那么只有在创建Father的时候来override此类属性的property,而如果想实现,那就必须用到类元,及metaclass,这东西简单,但是确实是所有类的始祖。

第二中方法,当然,也是在理解第一种方法之后,后来在读别的文章的时候发现了第二种方法。这里写出来方便大家理解。class Grandfather(object):

mylist = []

def __init__(self):

pass

class Father(Grandfather):

class __metaclass__(type):

@property

def mylist(cls):

return Grandfather.mylist

@mylist.setter

def mylist(cls, value): # @NoSelf

Grandfather.mylist = value

def __init__(self):

pass

Grandfather.mylist = [1, 2, 3, 4]

print Grandfather.mylist

print Father.mylist

Father.mylist = [‘a‘]

print Grandfather.mylist

print Father.mylist

这里就很容易发现在python中类是可以动态在任意合法位置使用合法缩进创建的。其实两者方法的原理一样。但是我个人还是更喜欢第一种,代码更加简洁明快。

才疏学浅,欢迎交流提意见彼此提高。

原文地址:http://zicowarn.blog.51cto.com/3815716/1792735

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值