如何在Python中定义类?
很简单,我正在学习Python,但找不到一个参考来告诉我如何编写以下内容:如何在Python中定义类?,python,Python,很简单,我正在学习Python,但找不到一个参考来告诉我如何编写以下内容: 公共类团队{ 私有字符串名称; 私人字符串标志; 私人int成员; 公共团队(){} //能手/二传手 } 后来: Team team = new Team(); team.setName("Oscar"); team.setLogo("http://...."); team.setMembers(10); 这是一个具有以下属性的类团队:名称/徽标/成员 编辑 经过几次尝试,我得到了这个: class Team:
公共类团队{
私有字符串名称;
私人字符串标志;
私人int成员;
公共团队(){}
//能手/二传手
}
后来:
Team team = new Team();
team.setName("Oscar");
team.setLogo("http://....");
team.setMembers(10);
这是一个具有以下属性的类团队:名称/徽标/成员
编辑
经过几次尝试,我得到了这个:
class Team:
pass
后来
这是Python的方式吗?感觉很奇怪(当然是来自强类型语言)
在Python中,您通常不编写getter和setter,除非您确实为它们提供了一个非平凡的实现(此时您使用属性描述符)。以下是我的建议:
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)
关于这方面的一些注意事项:
团队
继承自对象
。这使团队成为一个“新型班级”;自从在Python2.2中引入以来,这一直是Python中的推荐实践。(在Python3.0及更高版本中,即使您省略了(object)
符号,类也始终是“新样式的”;但是使用该符号并没有什么害处,并且使继承显式化。)下面是新样式类的堆栈溢出team
和team3
所做的那样。这些参数是命名的,因此您可以提供值作为位置参数(与team
一样),也可以使用参数=
表单,就像我对team3
所做的那样。当显式指定参数的名称时,可以按任意顺序指定参数Team()
的一部分,或者稍后将它们插入类实例中,这实际上并不重要。最终得到的类实例将是相同的True
。(您可以轻松地为团队
实例重载==
操作符,并在您说团队==team2
时让Python做正确的事情,但默认情况下不会发生这种情况。)
我在上面的答案中漏掉了一件事。如果在
\uuuu init\uuuu()
函数上执行可选参数操作,那么如果要提供“可变”作为可选参数,则需要小心
整数和字符串是“不可变的”。你永远无法在原地改变它们;相反,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
您需要知道的关键是:编译函数时,可选参数只计算一次。因此,如果在类的\uuuu init\uuuu()
中传递一个可变参数作为可选参数,那么类的每个实例都共享一个可变对象。这几乎不是你想要的
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
,然后测试传递的参数是否为None
,这项工作符合Python设计模式的要求,或者至少是您应该掌握的习惯用法。要编写您通常会做的类:
class Person:
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
要实例化类的实例,您需要执行以下操作
person1 = Person("Oscar", 40, "6ft")
person2 = Team("Danny", 12, "5.2ft")
您还可以设置默认值:
class Person:
def __init__(self):
self.name = "Daphne"
self.age = 20
self.height = "5.4ft"
要实例化这样的类集,您需要执行以下操作:
person3 = Person()
person3.name = "Joe"
person3.age = 23
person3.height = "5.11ft"
您会注意到,此方法与典型的Python字典交互非常相似。Martin,我的查找类Team:pass与您的示例有什么区别?您可以根据需要动态添加属性,但是,如果团队类始终包含这些属性,那么在类内部而不是外部定义这些属性就更清晰了。这对于文档编制很有用,因为它可以让查看您的类的人看到哪些属性是有用的。主要区别是在
Team()
之后,您已经将name、log、members设置为一些默认值;对于空类,最初没有设置任何属性。通常避免在以后添加属性,并在构造函数中设置所有属性,这样您就可以相信它们在所有方法中都存在。但是,如果可能的话,您也会尝试将它们初始化为正确的值(从构造函数参数),就像在Java中一样。@Pynt,怎么会这样?在我看来相当标准,所以如果有什么人们应该避免的事情,你能为我们详细介绍一下吗?如果你希望字符串的默认值为“”,而不是无,你可以在_init_;()函数中进行更改。+1有趣的是:如果使用了命名参数,我就不会得到“method init正好使用了4个参数0”错误消息@奥斯卡·雷耶斯:不。如果为它们提供了默认值,那么这些参数是可选的。我喜欢超越原始问题的清晰详细的讨论。非常感谢adam.gomaa.us链接似乎已断开(域名不存在?)。我建议有人将标题更改为更适合未来搜索的名称。类似于“用Python定义类的最佳方式”。@steveha:也许我真正的问题是,我该如何用Python编写这个类。。。
person1 = Person("Oscar", 40, "6ft")
person2 = Team("Danny", 12, "5.2ft")
class Person:
def __init__(self):
self.name = "Daphne"
self.age = 20
self.height = "5.4ft"
person3 = Person()
person3.name = "Joe"
person3.age = 23
person3.height = "5.11ft"