Python, создание объектов

133

Я пытаюсь изучить 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
1
Нет (без кавычек) - обычное неназначенное значение по умолчанию в python
monkut

Ответы:

174
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.

Wulfram
источник
17
почему вы инициализируете их как переменные класса до инициализации? (любопытно; не часто видел этот узор)
GoingTharn
7
Для удобства чтения. Помещая переменные класса вверху перед инициализацией, я могу быстро увидеть, какие переменные находятся в области действия класса, поскольку не все они могут быть установлены конструктором.
Wulfram
1
Здесь имя объекта, который является экземпляром класса Student, останется студентом, верно? Что, если мне нужно, чтобы при каждом вызове было несколько объектов с именами student01, student02, ... и так далее?
Yathi
9
Создание переменных класса, чтобы увидеть, какие переменные вашего экземпляра - ужасная практика. Для любых начинающих читателей: вместо этого посмотрите ответ @pyrospade.
anon01
2
Ваш пример вводит в заблуждение. Пожалуйста, используйте имена переменных класса, которые в действительности являются собственностью всех учащихся, а не злоупотребляйте свойством каждого учащегося. Например: используйте class Unicornи has_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, если она выполняет то же самое, что и Student.__init__.

смеситель
источник
Наш учитель дал нам программу test.py, которая проверяет, правильно ли мы решаем задачи. Вопрос хочет, чтобы я специально использовал функцию make_student. Конечная цель: s1 = make_student (имя, возраст, специальность), и теперь у меня есть все, что связано с s1. Но опять же, я не уверен, каким они хотят видеть s1? Я могу сделать это с помощью массива {'name': name..etc}, но это не дало мне правильного ответа, поэтому я предполагаю, что мне нужно реализовать то, что я узнал из классов и экземпляров,
Мохсен М. Альрашид
1
Так называемый шаблон "фабричный метод", когда вы используете метод или функцию для создания какого-либо объекта, вместо того, чтобы создавать их непосредственно в коде, является полезным шаблоном, он позволяет вам использовать приятные вещи, например, наследование , Посмотри;)
bracco23 01
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})()
pyrospade
источник
На самом деле, я предпочитаю не делать имя класса (объект): из соображений многословности. Документация Python, как правило, этого не делает. Но мне нравится «опасный» пример кормления в диктовке. docs.python.org/2/tutorial/classes.html
Вульфрам,
1
Я снимаю свой предыдущий комментарий. См. Stackoverflow.com/questions/4015417/… . Таким образом, на самом деле есть причина указать имя класса (объект):
Wulfram
1
В python нет конструктора :)
BigSack
Чем __init__()метод отличается от конструктора?
pyrospade
1
__init__не является конструктором, «потому что объект уже был построен к моменту __init__вызова, и у вас уже есть действительная ссылка на новый экземпляр класса». ( diveintopython.net/object_orient_framework/… )
Брайан Зи,
3

когда вы создаете объект с использованием предопределенного класса, сначала вы хотите создать переменную для хранения этого объекта. Затем вы можете создать объект и сохранить созданную вами переменную.

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

Фактически этот метод инициализации является конструктором класса. Вы можете инициализировать этот метод, используя некоторые атрибуты .. В этом случае, когда вы создаете объект, вам нужно будет передать некоторые значения для определенных атрибутов ..

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

 # creating an object.......

     student2=Student("smith",25)
GT_hash
источник