Python, membuat objek

132

Saya mencoba belajar python dan sekarang saya mencoba memahami kelas dan bagaimana memanipulasi mereka dengan instance.

Saya sepertinya tidak mengerti masalah latihan ini:

Membuat dan mengembalikan objek siswa yang nama, usia, dan jurusannya sama dengan yang diberikan sebagai input

def make_student(name, age, major)

Saya hanya tidak mengerti apa yang dimaksud dengan objek, apakah maksudnya saya harus membuat array di dalam fungsi yang menyimpan nilai-nilai ini? atau buat kelas dan biarkan fungsi ini ada di dalamnya, dan tetapkan instance? (sebelum pertanyaan ini saya diminta untuk membuat kelas siswa dengan nama, umur, dan jurusan di dalamnya)

class Student:
    name = "Unknown name"
    age = 0
    major = "Unknown major"
Mohsen M. Alrasheed
sumber
Baca dokumen model data, khususnya __init__metode ini relevan di sini: docs.python.org/2/reference/datamodel.html#object.__init__
wim
1
Tidak ada (tidak ada tanda kutip) adalah nilai default umum yang belum ditetapkan di python
monkut

Jawaban:

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

Perhatikan bahwa meskipun salah satu prinsip dalam filsafat Python adalah "harus ada satu - dan lebih disukai hanya satu - cara yang jelas untuk melakukannya" , masih ada banyak cara untuk melakukan ini. Anda juga dapat menggunakan dua cuplikan kode berikut untuk memanfaatkan kapabilitas dinamis 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

Saya lebih suka yang pertama, tetapi ada beberapa contoh di mana yang terakhir bisa berguna - yang ketika bekerja dengan database dokumen seperti MongoDB.

Wulfram
sumber
17
mengapa Anda menginisialisasi mereka sebagai variabel kelas sebelum init Anda? (penasaran; belum sering melihat pola itu)
GoingTharn
7
Untuk tujuan keterbacaan. Dengan meletakkan variabel kelas di dekat bagian atas sebelum init, saya dapat dengan cepat melihat variabel mana yang berada dalam ruang lingkup kelas karena mereka mungkin tidak semuanya diatur oleh konstruktor.
Wulfram
1
Di sini nama objek yang merupakan instance dari kelas Siswa akan tetap menjadi siswa, kan? Bagaimana jika saya ingin beberapa objek di setiap panggilan dengan nama student01, student02, .. dan seterusnya?
Yathi
9
Membuat variabel kelas untuk melihat variabel instan Anda adalah praktik yang buruk. Untuk setiap pembaca pemula: lihat jawaban @ pyrospade.
anon01
2
Teladan Anda menyesatkan. Silakan gunakan nama variabel kelas yang pada kenyataannya merupakan properti semua siswa, daripada menyalahgunakan properti setiap siswa. Misalnya: gunakan class Unicorndan has_hooves = Truebukannya name = "".
Tim Kuipers
49

Buat kelas dan berikan __init__metode:

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

Sekarang, Anda dapat menginisialisasi instance Studentkelas:

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

Meskipun saya tidak yakin mengapa Anda memerlukan make_studentfungsi siswa jika melakukan hal yang sama Student.__init__.

Blender
sumber
Guru kami memberi kami program test.py yang menguji jika kami melakukan masalah dengan benar. Pertanyaannya ingin saya secara khusus menggunakan fungsi make_student. Tujuan akhirnya adalah: s1 = make_student (nama, umur, jurusan) dan sekarang saya memiliki semua yang ditugaskan untuk s1. Tapi sekali lagi saya tidak yakin apa yang mereka inginkan s1? Saya bisa melakukan ini dengan array {'name': name..etc} tapi itu tidak memberi saya jawaban yang benar jadi saya berasumsi saya perlu mengimplementasikan apa yang saya pelajari dari kelas dan instance
Mohsen M. Alrasheed
1
Pola yang disebut "metode pabrik", pola di mana Anda menggunakan metode atau fungsi untuk membuat objek semacam daripada membuat langsung dalam kode, adalah pola yang bermanfaat, memungkinkan Anda untuk mengeksploitasi hal-hal baik tentang warisan misalnya . Lihatlah;)
bracco23
28

Objek adalah turunan dari kelas. Kelas hanyalah cetak biru untuk objek. Jadi, berikan definisi kelas Anda -

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

Anda dapat membuat make_studentfungsi dengan menetapkan atribut secara eksplisit ke instance baru Student-

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

Tapi mungkin lebih masuk akal untuk melakukan ini di 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

Konstruktor dipanggil saat Anda menggunakan Student(). Itu akan mengambil argumen yang didefinisikan dalam __init__metode ini. Tanda tangan konstruktor sekarang pada dasarnya akan Student(name, age, major).

Jika Anda menggunakannya, maka make_studentfungsi itu sepele (dan berlebihan) -

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

Untuk bersenang-senang, berikut adalah contoh cara membuat make_studentfungsi tanpa mendefinisikan kelas. Tolong jangan coba ini di rumah.

def make_student(name, age, major):
    return type('Student', (object,),
                {'name': name, 'age': age, 'major': major})()
pyrospade
sumber
Sebenarnya, saya lebih suka untuk tidak melakukan Nama kelas (objek): karena alasan verbositas. Dokumentasi Python cenderung tidak melakukannya juga. Saya suka contoh "berbahaya" memberi makan di dict. docs.python.org/2/tutorial/classes.html
Wulfram
1
Saya menarik komentar saya sebelumnya. Lihat stackoverflow.com/questions/4015417/… . Jadi sebenarnya ada alasan untuk mengeja Nama kelas (objek):
Wulfram
1
Tidak ada konstruktor dalam python :)
BigSack
Bagaimana __init__()metode berbeda dari konstruktor?
pyrospade
1
__init__bukan konstruktor, "karena objek sudah dibangun pada saat __init__dipanggil, dan Anda sudah memiliki referensi yang valid ke instance baru kelas." ( diveintopython.net/object_oriented_framework/… )
Brian Z
3

ketika Anda membuat objek menggunakan kelas yang telah ditentukan, pada awalnya Anda ingin membuat variabel untuk menyimpan objek itu. Kemudian Anda bisa membuat objek dan menyimpan variabel yang Anda buat.

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

Sebenarnya metode init ini adalah konstruktor dari class. Anda dapat menginisialisasi metode tersebut menggunakan beberapa atribut .. Pada titik itu, ketika Anda membuat objek, Anda harus memberikan beberapa nilai untuk atribut tertentu ..

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

 # creating an object.......

     student2=Student("smith",25)
GT_hash
sumber