初始化对象变量-Java方法,Python方法?

2024-06-16 10:13:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个对象需要传递4-5个值。举例说明:

class Swoosh():
    spam = ''
    eggs = ''
    swallow = ''
    coconut = ''

    [... methods ...]

现在,使用Swoosh的方法是:

swoosh = Swoosh()
swoosh.set_spam('Spam!')
swoosh.set_eggs('Eggs!')
swoosh.set_swallow('Swallow!')
swoosh.set_coconut('Migrated.')

我怀疑这是否是Pythonic,还是Java的影响太大。还是只是必要的?另外,如果您想知道为什么我使用setter而不是简单地访问对象变量,那么必须在那里进行一些基本的验证,因此使用set_方法。

我想我可以提供一种不同的方法来初始化一个Swoosh-提供一个__init__()来接受一个dict/list

不管怎样,我只是想从一个对这方面有经验的人那里寻求帮助/建议。

提前感谢您对此的任何意见。


Tags: 对象方法spameggsclassmethodssetcoconut
3条回答

基本验证可以通过重写适当的get and set methods on the class(如果在所有情况下都需要进行验证)或使用内置的^{}更改特定属性来完成。记住,Python is not Java(当然,Java is not Python, either)。

至于如何创建类,您有两个选择:

1)使用带关键字参数的__init__方法,让人们向您的构造函数提供尽可能多或少的内容:

class Swoosh(object): # Get new-object goodness
    def __init__(self, spam='', eggs='', swallow='', coconut=''):
        # We are going to be using properties in this example
        self._spam = spam
        self._eggs = eggs
        self._swallow = swallow
        self._coconut = coconut

2)继续按原样做,但将类属性更新为实例属性:

class Swoosh(object): # Get new-object goodness
    def __init__(self):
        self.spam = ''
        self.eggs = ''
        self.swallow = ''
        self.coconut = ''

按照您目前的做法,Swoosh的每个实例都为这些变量共享相同的值,并且更改Swoosh上的spam的值将更改Swoosh的每个实例的Swoosh的值,这些实例没有设置具有相同名称的实例属性(这可能不是您想要的)

不管怎样,您都应该考虑删除getter和setter并用属性替换它们(何时这样做当然取决于这个API的公开性和广泛使用程度):

# Inside class Swoosh's definition
@property
def spam(self):
    return self._spam
@spam.setter
def spam(self, value):
    # Validate that it's really SPAM, not WHAM!
    # And only then replace the underlying value
    self._spam = value
@spam.deleter
def spam(self):
    del self._spam
# Rinse and repeat for other properties that need access control

首先你用的是老式的课程。你应该使用new style classes that inherit from ^{}

class Swoosh(object):

定义一个接受参数的__init__方法绝对是python式的做法:

def __init__(self,spam,eggs,swallow,coconut):
    self.spam = spam
    self.eggs = eggs
    self.swallow = swallow
    self.coconut = coconut

这将允许您:

s = Swoosh('Spam!','Eggs','Swallow','Migrated')

与任何其他Python函数一样,__init__方法可以有参数的默认值,例如

def __init__(self,spam,eggs,swallow,coconut='Migrated.'):
        self.spam = spam
        self.eggs = eggs
        self.swallow = swallow
        self.coconut = coconut

如果希望在设置属性时对其进行验证,则应使用标准^{} attributes,而不是创建自己的setter。如果这样做,您可以在代码中使用myobject.spam,就像使用普通属性一样,但setter方法仍在运行。

例如:

@property
def spam(self):
    """I'm the 'spam' property."""
    return self._spam

@spam.setter
def spam(self, value):
    if not value.endswith("!"):
        raise ValueError("spam must end with !")
    # Store the value in "private" _spam attribute
    self._spam = value

@spam.deleter
def spam(self):
    del self._spam

注意:property将不工作,除非您使用如上所述的新样式类。

在您的示例中,您有:

class Swoosh():
    spam = ''
    eggs = ''
    swallow = ''
    coconut = ''

这通常是一种快速设置对象属性默认值的方法。很好,但你需要了解实际情况。现在的情况是您正在设置的属性。如果一个对象没有属性,Python将查看它是否在类上定义并从中返回值(因为这是您想要的方法)。

如果您想为对象属性设置默认值,那么最好像上面描述的那样为__init__中的参数设置默认值,而不是使用class属性。

首先,这:

class Swoosh():
    spam = ''
    eggs = ''
    swallow = ''
    coconut = ''

设置类属性spameggs等。然后,您的set-spam方法可能会继续创建同名的对象属性来隐藏类属性。换句话说,定义这些属性没有效果,只是混淆了一些东西。

如果所有变量都是可选的,我会这样做:

class Swoosh():
    def __init__(self, spam="", eggs="", swallow="", coconut=""):
        self.spam = spam
        self.eggs = eggs
        self.swallow = swallow
        self.coconut = coconut

然后可以创建如下对象:

o1 = Swoosh(eggs="Eggs!", coconut="Carried by the husk")

如果,比如说,垃圾邮件和鸡蛋是强制性的,那么用

    def __init__(self, spam, eggs, swallow="", coconut=""):

不要使用setter和getter。如果以后需要,可以通过向类中添加以下代码来无缝地将常规属性替换为属性:

    def get_spam(self):
        return self._spam
    def set_spam(self, value):
        self._spam = " ".join([str(value)] * 5)
    spam = property(get_spam, set_spam)

有了上述变化,这:

o2 = Swoosh(eggs="yes", spam="spam")
print o2.spam

印刷品

spam spam spam spam spam

注意:正如Dave Webb在他的回答中指出的,要使属性工作,您需要子类object,除非您使用python 3.0+,在这种情况下,类隐式地子类object。噢,do跟随Sean Vieira的链接,可以看到Python不是Java文章。这是必读的。

相关问题 更多 >