Python 2.7 中 __init__ 对 self 的行为

1 投票
3 回答
1256 浏览
提问于 2025-04-16 06:45

我有一个关于Python的问题,我觉得应该挺简单的——如果我有什么不好的做法,请随时告诉我。我有以下这段代码:

class User(dict,BaseDBI):
    def __init__(self,uid=None,username=None):
        self['uid']=str(uuid())     
        if uid == None and username is not None:            
            uid_struct = self.Get('data/username.kch',username)         
            if uid_struct is not None:
                self = self.Get('data/user.kch',uid_struct['uid'])

从这段代码可以看出,User其实就是一个扩展了的字典对象。它还访问了几个简单的获取和设置方法,涉及到一些京都内存数据库文件。我加了一些打印语句来跟踪发生了什么,所有的内容都设置得很好。但是,当我创建一个User对象(比如说):

user = User(username='someusername')

然后打印这个用户时,我只得到了一个新的字典对象,里面只有在__init__的第一行生成的全新uid

谢谢你们的建议!

3 个回答

0

你需要调用继承的构造函数。可以这样做:

def __init__(self,uid=None,username=None):
    dict.__init__(self)
    BaseDBI.__init__(self)

另外,把值赋给 self 只是会替换掉本地变量 self 的值。这对对象本身没有任何影响。

0

如果你想返回一个已经存在的对象,或者你的类的实例,你需要定义一个 __new__ 方法。

在调用 __init__ 方法之前,已经创建了一个新的实例。

2

在Python中,变量其实是指向对象的引用。当你给self赋值时,你只是替换了这个引用,并没有改变__init__返回的对象。

最简单的方法可能就是使用dict.update方法,把所有的键值对复制到self里。这样做应该是没问题的,因为你已经是从dict继承过来的。

继承适合用在像A是B这样的关系上。你说一个用户是一个字典,这没问题,但我怀疑用户是否真的是一个BaseDBI。更可能的是,你想让用户拥有一个数据库,这种情况下使用组合会更合适。这听起来可能有点挑剔,但这样可以避免你创建出奇怪和不合理的系统。

撰写回答