设置对象实例变量的正确方法

18 投票
4 回答
38456 浏览
提问于 2025-04-15 20:52

我正在写一个类,用来把用户插入到数据库里。在我深入之前,我想确认一下我的面向对象的方法是否清晰:

class User(object):

    def setName(self,name):

        #Do sanity checks on name
        self._name = name

    def setPassword(self,password):

        #Check password length > 6 characters
        #Encrypt to md5
        self._password = password

    def commit(self):

        #Commit to database

>>u = User()
>>u.setName('Jason Martinez')
>>u.setPassword('linebreak')
>>u.commit()

这样做对吗?

我应该把类的变量放在最上面吗?

我是否应该在所有类变量前面加一个下划线,来表示它们是私有的?

谢谢你的帮助。

4 个回答

3

在这段代码里,没有类变量,只有实例属性。建议使用属性,而不是访问器。而且最好在初始化的时候创建实例属性,最好是用传入的值来设置:

class User(object):
  def __init__(self, name, password='!!'):
    self.name = name
    self.password = password

  ...
9

使用一个下划线(_)并不能让你的属性变成私有的,这只是一个约定,表示这是一个内部属性,正常情况下不应该被外部代码访问。根据你的代码,_password 和 _name 这两个属性也是只读的。

我强烈建议你为你的类使用一个初始化方法,这个方法可以用来设置你的属性,即使是设置成默认值,比如 None。这样在你的提交方法中就会简单很多,因为你不需要再检查 _name 和 _password 属性是否存在(用 hasattr 来检查)。

在你的代码上使用 Pylint 工具。

23

据我所知,这样说是基本正确的,但你可以用属性来让代码更简洁。

class User(object):

    def _setName(self, name=None):
        self._name = name

    def _getName(self):
        return self._name

    def _setPassword(self, password):
        self._password = password

    def _getPassword(self):
        return self._password

    def commit(self):
        pass

    name = property(_getName, _setName)
    password = property(_getPassword, _setPassword)

>>u = User()
>>u.name = 'Jason Martinez'
>>u.password = 'linebreak'
>>u.commit()

还有一种很方便的基于装饰器的写法,文档里也有解释。

撰写回答