如何在Python中定义类?

如何在Python中定义类?,python,Python,很简单,我正在学习Python,但找不到一个参考来告诉我如何编写以下内容: 公共类团队{ 私有字符串名称; 私人字符串标志; 私人int成员; 公共团队(){} //能手/二传手 } 后来: Team team = new Team(); team.setName("Oscar"); team.setLogo("http://...."); team.setMembers(10); 这是一个具有以下属性的类团队:名称/徽标/成员 编辑 经过几次尝试,我得到了这个: class Team:

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

公共类团队{
私有字符串名称;
私人字符串标志;
私人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
    所做的那样。当显式指定参数的名称时,可以按任意顺序指定参数

  • 如果您需要使用getter和setter函数,也许是为了检查某些东西,那么在Python中可以声明特殊的方法函数。这就是马丁五世。Löwis说的是“财产描述符”。在Python中,通常认为简单地分配给成员变量,并简单地引用它们来获取它们是一种好的做法,因为如果需要,您可以随时添加属性描述符。(如果你从来都不需要它们,那么你的代码就不会那么凌乱,也不会花那么多时间去编写。额外奖励!)

  • 这里有一个关于属性描述符的好链接:

    注意:亚当·戈马的博客似乎已经从网上消失了。这里有一个链接,指向archive.org上保存的副本:

  • 如果将值指定为调用
    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"