Python, tạo đối tượng


132

Tôi đang cố gắng học python và bây giờ tôi đang cố gắng nắm bắt các lớp học và làm thế nào để thao túng chúng bằng các ví dụ.

Tôi dường như không thể hiểu vấn đề thực hành này:

Tạo và trả về một đối tượng sinh viên có tên, tuổi và chuyên ngành giống như các đối tượng được cung cấp làm đầu vào

def make_student(name, age, major)

Tôi chỉ không hiểu ý nghĩa của đối tượng, ý họ là tôi nên tạo một mảng bên trong hàm chứa các giá trị này? hoặc tạo một lớp và để hàm này nằm trong nó và gán các thể hiện? (trước câu hỏi này tôi đã được yêu cầu thành lập một lớp học sinh với tên, tuổi và chuyên ngành bên trong)

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

Đọc tài liệu mô hình dữ liệu, cụ thể __init__phương pháp có liên quan ở đây: docs.python.org/2/reference/datamodel.html#object.__init__
wim

1
Không có (không có dấu ngoặc kép) là giá trị mặc định chưa được gán phổ biến trong python
monkut

Câu trả lời:


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

Lưu ý rằng mặc dù một trong những nguyên tắc trong triết lý của Python là "nên có một cách tốt nhất và chỉ có một cách rõ ràng để làm điều đó" , vẫn còn nhiều cách để làm điều này. Bạn cũng có thể sử dụng hai đoạn mã sau để tận dụng các khả năng động của 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

Tôi thích cái trước, nhưng có những trường hợp cái sau có thể hữu ích - một là khi làm việc với cơ sở dữ liệu tài liệu như MongoDB.


17
Tại sao bạn lại khởi tạo chúng dưới dạng các biến lớp trước init của bạn? (tò mò; không thấy mô hình đó rất thường xuyên)
Đi vào

7
Đối với mục đích dễ đọc. Bằng cách đặt các biến lớp gần đầu trước khi khởi tạo, tôi có thể nhanh chóng xem biến nào nằm trong phạm vi lớp vì chúng có thể không được đặt bởi hàm tạo.
Wulfram

1
Ở đây tên của đối tượng là ví dụ của lớp Học sinh sẽ vẫn là học sinh phải không? Điều gì xảy ra nếu tôi muốn nhiều đối tượng trong mỗi cuộc gọi với tên student01, student02, .. và như vậy?
Yathi

9
Tạo các biến lớp để xem biến thể hiện của bạn là thực tế khủng khiếp. Đối với bất kỳ độc giả mới làm quen: thay vào đó hãy xem câu trả lời của @ pyrospade.
anon01

2
Ví dụ của bạn là sai lệch. Vui lòng sử dụng tên biến lớp trong thực tế là tài sản của tất cả học sinh, thay vì sử dụng sai tài sản của mỗi học sinh. Ví dụ: sử dụng class Unicornhas_hooves = Truethay vì name = "".
Tim Kuipers

49

Tạo một lớp và cung cấp cho nó một __init__phương thức:

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

Bây giờ, bạn có thể khởi tạo một thể hiện của Studentlớp:

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

Mặc dù tôi không chắc tại sao bạn cần một make_studentchức năng sinh viên nếu nó làm điều tương tự như Student.__init__.


Giáo viên của chúng tôi đã cho chúng tôi một chương trình test.txt kiểm tra nếu chúng tôi thực hiện đúng các vấn đề. Câu hỏi muốn tôi đặc biệt sử dụng hàm make_student. Mục tiêu cuối cùng là: s1 = make_student (tên, tuổi, chuyên ngành) và bây giờ tôi có mọi thứ được gán cho s1. Nhưng một lần nữa tôi không chắc họ muốn s1 là gì? Tôi có thể làm điều này với một mảng {'name': name..etc} nhưng điều đó không cho tôi một câu trả lời đúng vì vậy tôi cho rằng tôi cần phải thực hiện những gì tôi học được từ các lớp và trường hợp
Mohsen M. Alrasheed

1
Mẫu được gọi là "phương thức xuất xưởng", mẫu mà bạn sử dụng một phương thức hoặc hàm để tạo một đối tượng thuộc loại nào đó thay vì tạo chúng trực tiếp trong mã, là một mẫu hữu ích, nó cho phép bạn khai thác những điều hay về thừa kế chẳng hạn . Nhìn lên;)
bracco23

28

Đối tượng là các thể hiện của các lớp. Các lớp chỉ là bản thiết kế cho các đối tượng. Vì vậy, đưa ra định nghĩa lớp học của bạn -

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

Bạn có thể tạo một make_studenthàm bằng cách gán rõ ràng các thuộc tính cho một thể hiện mới của Student-

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

Nhưng có lẽ có ý nghĩa hơn khi làm điều này trong một hàm tạo ( __init__) -

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

Hàm tạo được gọi khi bạn sử dụng Student(). Nó sẽ lấy các đối số được định nghĩa trong __init__phương thức. Chữ ký của nhà xây dựng bây giờ về cơ bản là Student(name, age, major).

Nếu bạn sử dụng nó, thì một make_studenthàm là tầm thường (và không cần thiết) -

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

Để giải trí, đây là một ví dụ về cách tạo make_studenthàm mà không cần xác định lớp. Xin đừng thử điều này ở nhà.

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

Trên thực tế, tôi không thích làm Tên lớp (đối tượng): vì lý do dài dòng. Tài liệu Python có xu hướng không làm điều đó là tốt. Tôi thích ví dụ "nguy hiểm" của việc cho ăn trong một dict mặc dù. docs.python.org/2/tutorial/groupes.html
Wulfram

1
Tôi rút lại nhận xét trước đây của tôi. Xem stackoverflow.com/questions/4015417/ . Vì vậy, thực sự có một lý do để đánh vần Tên lớp (đối tượng):
Wulfram

1
Không có nhà xây dựng nào trong python :)
BigSack

Làm thế nào là __init__()phương pháp khác nhau từ một constructor?
pyrospade

1
__init__không phải là một hàm tạo, "bởi vì đối tượng đã được xây dựng theo thời gian __init__được gọi và bạn đã có một tham chiếu hợp lệ cho thể hiện mới của lớp." ( diveintopython.net/object_oriented_framework/ mẹo )
Brian Z

3

khi bạn tạo một đối tượng bằng cách sử dụng lớp định trước, lúc đầu bạn muốn tạo một biến để lưu trữ đối tượng đó. Sau đó, bạn có thể tạo đối tượng và lưu trữ biến mà bạn đã tạo.

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

Trên thực tế phương thức init này là hàm tạo của lớp. Bạn có thể khởi tạo phương thức đó bằng cách sử dụng một số thuộc tính .. Trong thời điểm đó, khi bạn tạo một đối tượng, bạn sẽ phải truyền một số giá trị cho các thuộc tính cụ thể ..

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

 # creating an object.......

     student2=Student("smith",25)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.