Python,创建对象


132

我正在尝试学习python,现在我试图摆脱类的困扰,以及如何使用实例操纵它们。

我似乎无法理解这个练习问题:

创建并返回其名称,年龄和专业与输入相同的学生对象

def make_student(name, age, major)

我只是不了解对象的含义,是否意味着我应该在包含这些值的函数内创建一个数组?或创建一个类,让该函数位于其中,并分配实例?(在问这个问题之前,我被要求开设一个学生班,里面要说姓名,年龄和专业)

class Student:
    name = "Unknown name"
    age = 0
    major = "Unknown major"

阅读数据模型文档,特别__init__是与该方法相关的文档: docs.python.org/2/reference/datamodel.html#object.__init__
wim 2013年

1
None(无引号)是python中常见的未分配默认值
monkut 2013年

Answers:


173
class Student(object):
    name = ""
    age = 0
    major = ""

    # The class "constructor" - It's actually an initializer 
    def __init__(self, name, age, major):
        self.name = name
        self.age = age
        self.major = major

def make_student(name, age, major):
    student = Student(name, age, major)
    return student

请注意,即使Python哲学中的原则之一是“应该有一个,最好只有一个,这是显而易见的方式”,但仍然有多种方式可以做到这一点。您还可以使用以下两个代码段来利用Python的动态功能:

class Student(object):
    name = ""
    age = 0
    major = ""

def make_student(name, age, major):
    student = Student()
    student.name = name
    student.age = age
    student.major = major
    # Note: I didn't need to create a variable in the class definition before doing this.
    student.gpa = float(4.0)
    return student

我更喜欢前者,但在某些情况下后者可能有用–一种是在使用文档数据库(如MongoDB)时。


17
为什么在初始化之前将它们初始化为类变量?(很好奇;没有经常看到这种模式)
GoingTharn 2013年

7
出于可读性目的。通过将类变量放在初始化之前的顶部附近,我可以快速查看哪些变量在类范围内,因为它们可能不是全部由构造函数设置的。
Wulfram 2013年

1
在这里,作为类Student的实例的对象的名称将保持为学生对吗?如果我每次通话都希望有多个名称为Student01,student02等的对象怎么办?
Yathi 2014年

9
创建类变量以查看您的实例变量是一种糟糕的做法。对于任何新手读者:请改用@pyrospade的答案。
anon01 '18

2
您的示例具有误导性。请使用实际上是所有学生的财产的类变量名,而不是滥用每个学生的财产。例如:使用class Unicornhas_hooves = True代替name = ""
蒂姆·库珀斯

49

创建一个类并为其提供__init__方法:

class Student:
    def __init__(self, name, age, major):
        self.name = name
        self.age = age
        self.major = major

    def is_old(self):
        return self.age > 100

现在,您可以初始化Student该类的实例:

>>> s = Student('John', 88, None)
>>> s.name
    'John'
>>> s.age
    88

尽管我不知道make_student如果做与相同的功能为什么为什么需要一个学生函数Student.__init__


我们的老师给了我们一个test.py程序,用来测试我们是否正确完成了问题。这个问题想让我专门使用make_student函数。最终目标是:s1 = make_student(姓名,年龄,专业),现在我已将所有内容分配给s1。但是我不确定他们想要s1是什么?我可以使用数组{'name':name..etc}来做到这一点,但这并没有给出正确的答案,因此我假设我需要实现从类和实例中学到的知识
Mohsen M. Alrasheed

1
所谓的“工厂方法”模式是一种有用的模式,您可以在其中使用一种方法或函数来创建某种对象,而不是直接在代码中直接创建它们,例如, 。查找;)
bracco23'1

28

对象是类的实例。类只是对象的蓝图。因此,根据您的类定义-

# Note the added (object) - this is the preferred way of creating new classes
class Student(object):
    name = "Unknown name"
    age = 0
    major = "Unknown major"

您可以make_student通过将属性明确分配给Student- 的新实例来创建函数

def make_student(name, age, major):
    student = Student()
    student.name = name
    student.age = age
    student.major = major
    return student

但是在构造函数(__init__)中执行此操作可能更有意义-

class Student(object):
    def __init__(self, name="Unknown name", age=0, major="Unknown major"):
        self.name = name
        self.age = age
        self.major = major

使用时会调用构造函数Student()。它将采用__init__方法中定义的参数。现在,构造函数签名实际上将是Student(name, age, major)

如果使用该make_student函数,那么函数是微不足道的(并且是多余的)-

def make_student(name, age, major):
    return Student(name, age, major)

为了好玩,这里有一个示例,说明如何在make_student不定义类的情况下创建函数。请不要在家尝试。

def make_student(name, age, major):
    return type('Student', (object,),
                {'name': name, 'age': age, 'major': major})()

实际上,出于冗长的原因,我宁愿不执行类Name(object):。Python文档往往也没有做到这一点。不过,我喜欢喂字典的“危险”例子。 docs.python.org/2/tutorial/classes.html
Wulfram

1
我撤回了先前的评论。参见stackoverflow.com/questions/4015417/…。因此,实际上有理由拼出类Name(object):
Wulfram

1
python中没有构造函数:)
BigSack 2014年

__init__()方法与构造函数有何不同?
pyrospade 2014年

1
__init__不是构造函数,“因为在调用时该对象已经被构造__init__,并且您已经具有对该类新实例的有效引用”。(diveintopython.net/object_oriented_framework/...
布赖恩ž

3

使用predefine类创建对象时,首先要创建一个用于存储该对象的变量。然后,您可以创建对象并存储您创建的变量。

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

实际上,此init方法是class的构造方法。您可以使用一些属性来初始化该方法。在这一点上,创建对象时,您将必须为特定属性传递一些值。

class Student:
      def __init__(self,name,age):
            self.name=value
            self.age=value

 # creating an object.......

     student2=Student("smith",25)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.