如何在Python中定义一个类?

时间:2009-09-30 01:02:17

标签: 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 );

这是一个具有属性的类Team:name / logo / members

修改 经过几次尝试,我得到了这个:

class Team:
    pass

后来

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

这是python方式吗?感觉奇怪(当然来自强类型语言)

3 个答案:

答案 0 :(得分:104)

以下是我的建议:

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)我宣布团队继承自object。这使得Team成为一个“新风格”;这是Python中推荐的实践,因为它是在Python 2.2中引入的。 (在Python 3.0及更高版本中,即使您省略了(object)符号,类也总是“新风格”;但是使用该符号并没有什么坏处并使继承显式化。)这是一个StackOverflow discussion新式课程。

1)这不是必需的,但我使初始化程序采用可选参数,以便您可以在一行初始化实例,就像我对teamteam3所做的那样。这些参数已命名,因此您可以将值作为位置参数提供(与team一样),也可以像argument=一样使用team3表单。显式指定参数名称时,可以按任何顺序指定参数。

2)如果你需要有getter和setter函数,也许是为了检查一些东西,在Python中你可以声明特殊的方法函数。这就是Martin诉Löwis所说的“财产描述”时的意思。在Python中,通常认为简单地分配给成员变量并简单地引用它们来获取它们是一种好习惯,因为如果需要它们,您可以随后添加属性描述符。 (如果你从来不需要它们,那么你的代码就会变得更加混乱,花费你更少的时间来写。奖金!)

以下是有关属性描述符的良好链接: 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”作为可选参数,你需要小心。

整数和字符串是“不可变的”。你永远不能改变它们;相反,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__()中传递mutable作为可选参数,那么您的类的每个实例都会共享一个可变对象。这几乎不是你想要的。

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 provided list

k0 = K()
k1 = K()

k0.lst.append(1)

print k0.lst  # prints "[1]"
print k1.lst  # print "[]"

这个使用默认参数值None,然后测试参数传递is None的业务,可以作为Python设计模式,或者至少是你应该掌握的习惯用语。

答案 1 :(得分:51)

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

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

答案 2 :(得分:0)

要编写类,通常要做的是

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字典交互有很多相似之处