以下是我的建议:
class Team(object):
def __init__(self, name=None, logo=None, members=0):
self.name = name
self.logo = logo
self.members = members
team = Team("Oscar", "http://...", 10)
team2 = Team()
team2.name = "Fred"
team3 = Team(name="Joe", members=10)
对此的一些说明:
我声明Team 继承自object。这使得Team成为一个“新式班”;自从它在 Python 2.2 中引入以来,这一直是 Python 中的推荐做法。 (在 Python 3.0 及更高版本中,即使您省略了 (object) 表示法,类也始终是“新式”;但使用该表示法并没有害处,并且使继承变得明确。)这是一个堆栈溢出 discussion 的 new-样式类。
这不是必需的,但我让初始化程序采用可选参数,以便您可以在一行上初始化实例,就像我对 team 和 team3 所做的那样。这些参数是命名的,因此您可以提供值作为位置参数(如team),也可以使用argument= 形式,就像我对team3 所做的那样。显式指定参数名称时,可以按任意顺序指定参数。
如果你需要 getter 和 setter 函数,也许是为了检查一些东西,在 Python 中你可以声明特殊的方法函数。这就是 Martin v. Löwis 在说“财产描述符”时的意思。在 Python 中,通常认为简单地分配给成员变量并简单地引用它们以获取它们是一种很好的做法,因为您可以随时在以后需要时添加属性描述符。 (如果您从不需要它们,那么您的代码就不会那么混乱,并且花费您更少的时间来编写。奖金!)
这是一个关于属性描述符的好链接:http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/
注意:Adam Gomaa 的博客似乎已从网络上消失。这是 archive.org 上已保存副本的链接:
https://web.archive.org/web/20160407103752/http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/
- 在调用
Team() 时指定值或稍后将它们插入类实例并不重要。您最终得到的类实例将是相同的。
team = Team("Joe", "http://example.com", 1)
team2 = Team()
team2.name = "Joe"
team2.logo = "http://example.com"
team2.members = 1
print(team.__dict__ == team2.__dict__)
上面将打印True。 (您可以轻松地为Team 实例重载== 运算符,并使Python 在您说team == team2 时执行正确的操作,但默认情况下不会发生这种情况。)
我在上面的答案中遗漏了一件事。如果你在 __init__() 函数上做可选参数的事情,如果你想提供一个“可变”作为可选参数,你需要小心。
整数和字符串是“不可变的”。你永远无法原地改变它们;相反,Python 会创建一个新对象并替换您之前拥有的对象。
列表和字典是“可变的”。您可以永远保留同一个对象,添加和删除它。
x = 3 # The name "x" is bound to an integer object with value 3
x += 1 # The name "x" is rebound to a different integer object with value 4
x = [] # The name "x" is bound to an empty list object
x.append(1) # The 1 is appended to the same list x already had
您需要知道的关键点:可选参数仅在编译函数时计算一次。因此,如果您在类的__init__() 中将可变参数作为可选参数传递,那么类的每个实例都会共享一个可变对象。这几乎不是你想要的。
class K(object):
def __init__(self, lst=[]):
self.lst = lst
k0 = K()
k1 = K()
k0.lst.append(1)
print(k0.lst) # prints "[1]"
print(k1.lst) # also prints "[1]"
k1.lst.append(2)
print(k0.lst) # prints "[1, 2]"
解决方法很简单:
class K(object):
def __init__(self, lst=None):
if lst is None:
self.lst = [] # Bind lst with a new, empty list
else:
self.lst = lst # Bind lst with the provided list
k0 = K()
k1 = K()
k0.lst.append(1)
print(k0.lst) # prints "[1]"
print(k1.lst) # prints "[]"
使用默认参数值None,然后测试该参数是否通过is None,这符合 Python 设计模式,或者至少是您应该掌握的习语。