我有一个对象需要传递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
?
无论如何,我只是想从更有经验的人那里寻求帮助/建议。
提前感谢您对此的任何意见。
答案 0 :(得分:15)
首先,您使用的是旧式课程。你真的,真的应该使用new style classes that inherit from object
:
class Swoosh(object):
定义带参数的__init__
方法绝对是Pythonic的做事方式:
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
如果要在设置属性时验证属性,则应使用标准property
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
属性。
答案 1 :(得分:10)
首先,这个:
class Swoosh():
spam = ''
eggs = ''
swallow = ''
coconut = ''
设置类属性spam
,eggs
等。然后,您的set_spam方法可能会继续并创建同名的 object 属性隐藏类属性。换句话说,定义这些属性没有任何效果,只会让事情混淆。
如果所有变量都是可选的,我会这样做:
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和getters。如果您以后需要,可以通过向您的类添加这样的代码,将常规属性无缝替换为属性:
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在他的回答中所指出的那样,除非你使用python 3.0+,否则你需要继承object
属性才能工作,在这种情况下,类隐式地为{{{}} 1}}。哦,做跟随Sean Vieira链接到 Python不是Java 的文章。这是必读的。
答案 2 :(得分:4)
可以通过覆盖适当的get and set methods on the class(如果需要在所有情况下进行验证)或通过使用内置property
更改特定属性来完成基本验证。请记住,Python is not Java(当然,Java is not Python, either)。
至于你想如何创建课程,你有几个选择:
1)使用带有关键字args的__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
的每个实例都为这些变量分享相同的值,并且更改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
答案 3 :(得分:3)
要初始化Swoosh值,您有多种选择:
首先,构造函数args:
class Swoosh(object):
def __init__(self, spam, eggs, swallow, coconut):
self.spam = spam
self.eggs = eggs
self.swallow = swallow
self.coconut = coconut
然后像这样实现你的目标:
swoosh = Swoosh("spam", "eggs", "swallow", "coconut")
如果您需要更多控制获取/设置值的方式,可以使用property方法。
class Swoosh():
def __init__(self, spam, eggs, swallow, coconut):
self.spam = spam
self.eggs = eggs
self.swallow = swallow
self.coconut = coconut
def set_spam(self, value):
#do verification stuff
self._spam = value
def get_spam(self):
#do what you want/need before get the value
return self._spam
spam = property(get_spam, set_spam)
然后,每次调用swoosh.spam = spam_value
都会调用set_spam
方法,foo = swoosh.spam
会调用get_spam
方法。
答案 4 :(得分:1)
__init__()
函数是您在首次创建对象时用于设置值的功能。
例如
class Swoosh:
__init__(self, arg1, arg2, arg3):
self.arg1 = arg1
self.arg2 = arg2
self.arg3 = arg3