如何在Python中定义一个类

很简单,我正在学习Python,我找不到一个参考,告诉我如何编写以下内容:

public class Team { private String name; private String logo; private int members; public Team(){} // getters/setters } 

后来:

 Team team = new Team(); team.setName( "Oscar" ); team.setLogo( "http://...." ); team.setMembers( 10 ); 

这是一个团队与属性:名称/标志/成员

编辑经过几次尝试,我得到这个:

 class Team: pass 

后来

 team = Team() team.name="Oscar" team.logo="http://..." team.members=10 

这是python的方式? 感觉奇怪(当然来自强types语言)

 class Team: def __init__(self): self.name = None self.logo = None self.members = 0 

在Python中,你通常不写getter和setter,除非你真的有一个非平凡的实现(在这一点上你使用属性描述符)。

这是我会build议的:

 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) 

关于这个的一些笔记。

0)我声明该团队从objectinheritance。 这使得团队成为“新式的class级”。 这是自Python 2.2中引入以来在Python中被推荐的做法。 (在Python 3.0和更高版本中,即使忽略(object)表示法,类也总是“新风格”;但是这种表示法没有损害并使得inheritance是显式的。)下面是关于新风格类的StackOverflow 讨论 。

1)这不是必需的,但是我让初始化程序采用可选参数,以便可以在一行上初始化实例,就像我在teamteam3 。 这些参数是命名的,所以你可以提供值作为位置参数(与team ),或者你可以使用argument=forms,就像我对team3做的team3 。 当明确指定参数的名称时,可以按任意顺序指定参数。

2)如果你需要getter和setter函数,也许要检查一些东西,在Python中你可以声明特殊的方法函数。 这就是马丁诉路易斯所说的“地产描述”的意思。 在Python中,简单地分配给成员variables并简单地引用它们来获取它们是一种好的做法,因为如果你需要的话,你可以随时在属性描述符中添加它们。 (如果你永远不需要它们,那么你的代码就不那么混乱了,而且你花的时间也越来越less,奖金!)

这里有一个很好的链接关于属性描述: http : //adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

3)如果您指定值作为对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实例重载==操作符,并且当你说team == team2时,Python会做正确的事情,但是默认情况下这不会发生。


编辑:我遗漏了上面的答案中的一件事,我想现在添加它。 如果你在__init__()函数上做了可选参数的话,如果你想提供一个“mutable”作为一个可选的参数,你需要小心。

整数和string是“不可变的”。 你永远不能改变它们。 Python会创build一个新的对象,并取代以前的对象。

列表和字典是“可变的”。 你可以永远保持同一个对象,添加并删除它。

 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__()为可选parameter passing一个可变参数,那么你的类的每个实例共享一个可变对象。 这几乎从来没有你想要的。

 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]" 

解决scheme非常简单:

 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 provided list k0 = K() k1 = K() k0.lst.append(1) print k0.lst # prints "[1]" print k1.lst # print "[]" 

这个使用默认参数值None ,然后testing传递的参数is None ,可以作为Pythondevise模式,或者至less是一个你应该掌握的习惯用法。