python类可以与parent classe共享变量

时间:2016-09-29 14:07:44

标签: python inheritance

我有一个名为SocialPlatform的小组:

class SocialPlatform:
    nb_post = 0

    def __init__(self, data):
        self.data = data
        self._init_type()
        self.id_post = self._init_id_post()

    @classmethod
    def _init_id_post(cls):
        cls.nb_post += 1
        return cls.nb_post

以及继承自SocialPlatform的其他三个类:

class Facebook(SocialPlatform):
    _NAME = 'facebook'

    @classmethod
    def get_class_name(cls):
        return cls._NAME

    # code here


class Twitter(SocialPlatform):
    _NAME = 'twitter'

    @classmethod
    def get_class_name(cls):
        return cls._NAME

    # code here


class Instagram(SocialPlatform):
    _NAME = 'instagram'

    @classmethod
    def get_class_name(cls):
        return cls._NAME

    # code here

我的想法是每次创建nb_post的实例时增加SocialPlatform。我认为这个变量是在从SocialPlatform

继承的所有类之间共享的

所以我在我的主要功能中测试了它:

def main():
    post = Post() # an other class with stuff in it, it doesn't matter here
    social_platform = {
        'facebook': Facebook,
        'twitter': Twitter,
        'instagram': Instagram
    }
    while True:
        try:
            platform = social_platform[post.actual_post['header']['platform']](post.actual_post['data'])
        except KeyError:
            print 'Platform (%s) not implemented yet' % post.actual_post['header']['platform']
            sys.exit(84)

        print 'platform name : ' + platform.get_class_name()
        print 'post id : ' + str(platform.id_post)
        # platform.aff_content()

        post.pop()
        if not len(post.post):
            break

        print 'enter return to display next post'
        while raw_input() != "": pass

但是当我使用这段代码时,我得到了这个输出:

platform name : twitter
post id : 1
enter return to display next post

platform name : facebook
post id : 1
enter return to display next post

platform name : twitter
post id : 2

使用此方法{@ 1}}在Twitter,Facebook或Instagram实例之间共享,而不是所有这些。

所以我的问题是:在python中有没有办法做到这一点?

4 个答案:

答案 0 :(得分:1)

您必须在增量表达式中显式引用基类:

def _init_id_post(cls):
    cls.nb_post += 1
    return cls.nb_post

应该是:

def _init_id_post(cls):
    SocialPlatform.nb_post += 1
    return SocialPlatform.nb_post

按照:

How to count the number of instance of a custom class?

答案 1 :(得分:1)

当找不到属性时,它将在更高级别上查找。分配时,虽然使用了最本地的级别。

例如:

class Foo:
    v = 1

a = Foo()
b = Foo()

print(a.v) # 1: v is not found in "a" instance, but found in "Foo" class
Foo.v = 2 # modifies Foo class's "v"
print(a.v) # 2: not found in "a" instance but found in class
a.v = 3 # creates an attribute on "a" instance, does not modify class "v"
print(Foo.v) # 2
print(b.v) # 2: not found in "b" instance but found in "Foo" class

此处_init_id_post被宣布为classmethod,您正在cls.nb_post = cls.nb_post + 1。 在此表达式中,第二次cls.nb_post出现时将引用SocialPlatform,然后您在引用cls或{{1}的Twitter对象上进行分配} class,而不是Instagram。 当您在同一个类上再次调用它时,第二个SocialPlatform出现将不会引用cls.nb_post,因为您在SocialPlatform类的级别创建了属性(例如)。

解决方案不是使用Twitter,而是使用cls(并将其设为SocialPlatform.nb_post += 1

答案 2 :(得分:1)

   class A():
       n = 0

       def __init__(self):
           A.n += 1



    class B(A):

        def __init__(self):
            super(B, self).__init__()


    class C(A):

        def __init__(self):
            super(C, self).__init__()


a  = A()
print(a.n) #prints 1
b = B()
print(a.n) #prints 2
c = C()
print(a.n) #prints 3

我认为你可以自己弄清楚其余部分。祝你好运!

答案 3 :(得分:0)

这对我有用:

class SocialPlatform(object):
  nb_post = 0
  def __init__(self):
    self.id_post = A.nb_post
    A.increment()

  @classmethod
  def increment(cls):
    cls.nb_post += 1

class Facebook(SocialPlatform):
  pass

class Twitter(SocialPlatform):
  pass

然后:

>>> a = Facebook()
>>> b = Twitter()
>>> c = Twitter()
>>>
>>> a.id_post
0
>>> b.id_post
1
>>> c.id_post
2