Python, criando objetos


132

Estou tentando aprender python e agora estou tentando pegar o jeito das classes e como manipulá-las com instâncias.

Não consigo entender esse problema de prática:

Crie e retorne um objeto de aluno cujo nome, idade e maior sejam iguais aos dados fornecidos como entrada

def make_student(name, age, major)

Eu simplesmente não entendo o que isso significa por objeto. Eles significam que eu deveria criar uma matriz dentro da função que contém esses valores? ou criar uma classe e deixar essa função estar dentro dela e atribuir instâncias? (antes desta pergunta, pediram-me para montar uma turma com nome, idade e curso principal)

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

Leia os documentos do modelo de dados, especificamente o __init__método é relevante aqui: docs.python.org/2/reference/datamodel.html#object.__init__
wim

1
Nenhum (sem aspas) é o comum não atribuído valor padrão em python
monkut

Respostas:


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

Observe que, embora um dos princípios da filosofia do Python seja "deve haver um - e de preferência apenas um - maneira óbvia de fazê-lo" , ainda existem várias maneiras de fazer isso. Você também pode usar os dois trechos de código a seguir para aproveitar os recursos dinâmicos do 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

Prefiro o primeiro, mas há casos em que o último pode ser útil - um quando se trabalha com bancos de dados de documentos como o MongoDB.


17
por que você as inicializa como variáveis ​​de classe antes do seu init? (curioso, não vi esse padrão muito frequentemente)
GoingTharn

7
Para fins de legibilidade. Ao colocar as variáveis ​​de classe perto do topo antes do init, posso ver rapidamente quais variáveis ​​estão no escopo da classe, pois nem todas podem ser definidas pelo construtor.
Wulfram

1
Aqui o nome do objeto que é a instância da classe Student permanecerá aluno, certo? E se eu quiser vários objetos em cada chamada com o nome student01, student02, .. e assim por diante?
Yathi

9
Criar variáveis ​​de classe para ver quais são as variáveis ​​de sua instância é uma prática terrível. Para qualquer leitor iniciante: observe a resposta do @ pyrospade.
Anon01 26/0318

2
Seu exemplo é enganoso. Por favor, use nomes de variáveis ​​de classe que, na realidade, são propriedade de todos os alunos, em vez de usar indevidamente uma propriedade de cada aluno. Por exemplo: use class Unicorne em has_hooves = Truevez de name = "".
precisa

49

Crie uma classe e forneça um __init__método:

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

Agora, você pode inicializar uma instância da Studentclasse:

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

Embora eu não saiba por que você precisa de uma make_studentfunção de aluno, se ela faz a mesma coisa que Student.__init__.


Nosso professor nos deu um programa test.py que testa se solucionamos os problemas corretamente. A pergunta quer que eu use especificamente a função make_student. O objetivo final é: s1 = make_student (nome, idade, maior) e agora tenho tudo atribuído a s1. Mas, novamente, não tenho certeza do que eles querem que seja o s1. Eu posso fazer isso com uma matriz {'name': name..etc}, mas isso não me deu uma resposta correta, por isso estou assumindo que preciso implementar o que aprendi com classes e instâncias
Mohsen M. Alrasheed

1
O chamado padrão de "método de fábrica", aquele em que você usa um método ou uma função para criar algum tipo de objeto, em vez de criá-los diretamente no código, é um padrão útil, pois permite explorar coisas interessantes sobre herança, por exemplo . Procurá-lo;)
bracco23

28

Objetos são instâncias de classes. Classes são apenas as plantas dos objetos. Então, dada a sua definição de classe -

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

Você pode criar uma make_studentfunção atribuindo explicitamente os atributos a uma nova instância de Student-

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

Mas provavelmente faz mais sentido fazer isso em um constructor ( __init__) -

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

O construtor é chamado quando você usa Student(). Aceitará os argumentos definidos no __init__método A assinatura do construtor agora seria essencialmente Student(name, age, major).

Se você usar isso, uma make_studentfunção é trivial (e supérflua) -

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

Por diversão, aqui está um exemplo de como criar uma make_studentfunção sem definir uma classe. Por favor não tente isto em casa.

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

Na verdade, prefiro não fazer a classe Name (object): por razões de verbosidade. A documentação do Python tende a não fazê-lo também. Eu gosto do exemplo "perigoso" de alimentar um ditado. docs.python.org/2/tutorial/classes.html
Wulfram

1
Retiro meu comentário anterior. Consulte stackoverflow.com/questions/4015417/… . Portanto, não há realmente uma razão para soletrar classe Nome (objeto):
Wulfram

1
Não há construtor em python :)
BigSack

Como o __init__()método é diferente de um construtor?
pyrospade

1
__init__não é um construtor ", porque o objeto já foi construído quando o tempo __init__é chamado e você já tem uma referência válida para a nova instância da classe". ( Diveintopython.net/object_oriented_framework/... )
Brian Z

3

Quando você cria um objeto usando a classe predefinida, primeiro deseja criar uma variável para armazenar esse objeto. Em seguida, você pode criar um objeto e armazenar a variável que você criou.

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

Na verdade, esse método init é o construtor da classe. Você pode inicializar esse método usando alguns atributos. Nesse ponto, ao criar um objeto, você precisará passar alguns valores para atributos específicos.

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

 # creating an object.......

     student2=Student("smith",25)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.