简体   繁体   English

新对象被先前的对象覆盖

[英]New object is being overwritten by previous object

I am currently trying simple python class example. 我目前正在尝试简单的python类示例。 I have a Parent Class (person) and a subclass (contact). 我有一个父类(人)和一个子类(联系人)。

I instantiate the child class two times with different objects c1 and c2. 我用不同的对象c1和c2实例化了子类两次。 The c2 is replacing the c1 . c2正在替换c1。 What am i doing wrong ? 我究竟做错了什么 ?

#!/bin/python3

import time
from time import sleep

class Person (object):
    id = 0
    name = None
    fields = {}

    def __init__(self):
        ctime = time.strftime("%Y-%m-%d %H:%M:%S")
        self.fields.update({"create_time":ctime,
                            "write_time" :ctime})
        Person.id+=1

    def check_keys (self,vals):
        for k in vals:
            if not k in self.fields.keys():
                raise Exception("Key %s doesnot exists"%k)

    def update(self,*args,**kwargs):
        vals = kwargs['vals']
        self.check_keys(vals)
        self.fields.update(vals)
        ctime = time.strftime("%Y-%m-%d %H:%M:%S")
        self.fields.update({"write_time":ctime})

    def write(self,*args,**kwargs):
        vals = kwargs['vals']
        self.check_keys(vals)
        self.fields.update(vals)

    def detail (self):
        print ("Model Name is ",self.name)
        for k,v in self.fields.items():
            print("key:",k," value:",v)
        print ("#"*50)

    def get_id(self):
        return self.id

class Contact (Person):
    name="contact"
    contact_id = 0
    fields = {
        'id':None,
        'name':None,
        'age':None,
    }

c1 = Contact()
c1.update(vals={'name':'sijan','age':31,'id':c1.get_id()})
sleep(1)
c1.update(vals={'name':'sijan Shs'})

print ("calling contact 2")

c2 = Contact()
c2.update(vals={'name':'Aurelia','age':32,'id':c2.get_id()})

print ("calling contact 1")
c1.detail()
print ("calling contact 1")
c2.detail()

Here is the sample output from the last 2 c1.detail() and c2.detail() 这是最后2个c1.detail()和c2.detail()的示例输出

calling contact 1
Model Name is  contact
key: id  value: 2
key: name  value: Aurelia
key: age  value: 32
key: create_time  value: 2017-03-19 15:35:54
key: write_time  value: 2017-03-19 15:35:54
##################################################
calling contact 2
Model Name is  contact
key: id  value: 2
key: name  value: Aurelia
key: age  value: 32
key: create_time  value: 2017-03-19 15:35:54
key: write_time  value: 2017-03-19 15:35:54
#################################################

I believe it should be : 我相信应该是:

calling contact 1
Model Name is  contact
key: id  value: 1
key: name  value: Sijan Shs
key: age  value: 31
key: create_time  value: 2017-03-19 15:35:53
key: write_time  value: 2017-03-19 15:35:54
##################################################
calling contact 2
Model Name is  contact
key: id  value: 2
key: name  value: Aurelia
key: age  value: 32
key: create_time  value: 2017-03-19 15:35:54
key: write_time  value: 2017-03-19 15:35:54
#################################################

I am spinning my head around trying to figure out what is going on wrong. 我正在四处寻找解决问题的方法。 If i use the parent class it works smooth (the behavior as predicted ie different data ). 如果我使用父类,它将工作顺利(行为如预期,即不同的数据)。 But i am having difficulty trying to understand why the subclass are behaving this way ? 但是我很难理解为什么子类会以这种方式运行? Am i missing some thing ? 我错过了什么吗?

UPDATE 更新

What i am trying to achieve is : 我想要达到的是:

I will have few more classes and each class will have their unique fields, ie forexample address for address name. 我将再有几个班级,每个班级都有其唯一的字段,例如,地址名称的地址。 How can i Achieve this without adding the field dictionary to the parent ? 我如何在不将字段字典添加到父级的情况下实现这一目标? Example

class Address(Person):
    fields={
       'address':None
    }

Thanks a lot guys, This is working, 非常感谢大家,这很有效,

#!/bin/python3

import time
from time import sleep

class Person (object):
    id = 0
    name = None
    fields = {}

    def __init__(self):
        ctime = time.strftime("%Y-%m-%d %H:%M:%S")
        self.fields.update({"create_time":ctime,
                            "write_time" :ctime})
        Person.id+=1

    def check_keys (self,vals):
        for k in vals:
            if not k in self.fields.keys():
                raise Exception("Key %s doesnot exists"%k)

    def update(self,*args,**kwargs):
        vals = kwargs['vals']
        self.check_keys(vals)
        self.fields.update(vals)
        ctime = time.strftime("%Y-%m-%d %H:%M:%S")
        self.fields.update({"write_time":ctime})

    def write(self,*args,**kwargs):
        vals = kwargs['vals']
        self.check_keys(vals)
        self.fields.update(vals)

    def detail (self):
        print ("Model Name is ",self.name)
        for k,v in self.fields.items():
            print("key:",k," value:",v)
        print ("#"*50)

    def get_id(self):
        return self.id

class Contact (Person):


    def __init__(self):
        self.name="contact"
        self.fields = {
            'id':None,
            'name':None,
            'age':None
        }
        super(Contact,self).__init__()


ca = Contact()
ca.update(vals={'name':'sijan','age':31,'id':ca.get_id()})
sleep(1)
ca.update(vals={'name':'sijan Shs'})
ca.detail()

cb = Contact()
cb.detail()
cb.update(vals={'name':'Aurelia','age':32,'id':cb.get_id()})

print ("calling contact 1")
ca.detail()
print ("calling contact 2")
cb.detail()

This is because you are referencing class variables instead of instance variables. 这是因为您引用的是类变量而不是实例变量。 From the docs : 文档

Generally speaking, instance variables are for data unique to each instance and class variables are for attributes and methods shared by all instances of the class: 一般来说,实例变量用于每个实例唯一的数据,而类变量用于类的所有实例共享的属性和方法:

 class Dog: kind = 'canine' # class variable shared by all instances def __init__(self, name): self.name = name # instance variable unique to each instance 

Instead, you could write your classes as follows: 相反,您可以按照以下方式编写类:

 class Person(object):
      self.id = 0
      self.name = None
      self.fields = {}

 # rest of the class ...

 class Contact (Person):
     self.name="contact"
     self.contact_id = 0
     self.fields = {
         'id':None,
         'name':None,
         'age':None,
     }

 # rest of the class ...

name , id , fields are class members and so new values are not instantiated when instances of Contact which inherits from Person are made. nameidfields是类成员,因此在制作从Person继承的Contact实例时,不会实例化新值。

What you want to do is for every new instance of Contact create a new set of properties name, id, fields. 您要为每个新的Contact实例创建一组新的属性名称,id,字段。

The code below does that. 下面的代码可以做到这一点。 Pay attention to how it defines id, name, fields to be add a the instance when it is initialed ( in the __init__ function) 注意它是如何定义ID,名称,在实例初始化时添加实例的字段的(在__init__函数中)

Since every person has name, id, fields I dont have to initiate them in the Contact class as well. 由于每个人都有姓名,ID和字段,因此我也不必在Contact类中启动它们。 See the definition of the Contact class for a cleaner implementation of the inheritance. 有关继承的更清晰实现,请参见Contact类的定义。

#!/bin/python3

import time
from time import sleep

class Person (object):
    # id = 0
    # name = None
    # fields = {}

    def __init__(self):
        self.id = 0
        self.name = None
        self.fields = {
            'id':None,
            'name':None,
            'age':None,
        }

        ctime = time.strftime("%Y-%m-%d %H:%M:%S")
        self.fields.update({"create_time":ctime,
                            "write_time" :ctime})
        self.id+=1

    def check_keys (self,vals):
        for k in vals:
            if not k in self.fields.keys():
                raise Exception("Key %s doesnot exists"%k)

    def update(self,*args,**kwargs):
        vals = kwargs['vals']
        self.check_keys(vals)
        self.fields.update(vals)
        ctime = time.strftime("%Y-%m-%d %H:%M:%S")
        self.fields.update({"write_time":ctime})

    def write(self,*args,**kwargs):
        vals = kwargs['vals']
        self.check_keys(vals)
        self.fields.update(vals)

    def detail (self):
        print ("Model Name is ",self.name)
        for k,v in self.fields.items():
            print("key:",k," value:",v)
        print ("#"*50)

    def get_id(self):
        return self.id

class Contact (Person):
    def __init__(self):
        super(Contact, self).__init__()
        self.contact_id = 0


c1 = Contact()
c1.update(vals={'name':'sijan','age':31,'id':c1.get_id()})
# sleep(1)
c1.update(vals={'name':'sijan Shs'})

print ("calling contact 2")

c2 = Contact()
c2.update(vals={'name':'Aurelia','age':32,'id':c2.get_id()})

print ("calling contact 1")
c1.detail()
print ("calling contact 1")
c2.detail()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM