Cách thông thường để thêm chức năng [phương thức] vào một lớp trong Python là định nghĩa các hàm trong phần thân của lớp. Có nhiều cách khác để thực hiện điều này có thể hữu ích trong các tình huống khác nhau
Đây là cách truyền thống
class A[object]: def print_classname[self]: print self.__class__.__name__
Phương thức cũng có thể được định nghĩa bên ngoài phạm vi của lớp. Điều này cho phép hàm “print_classname” được sử dụng như một hàm độc lập và như một phương thức của lớp
def print_classname[a]: print a.__class__.__name__ class A[object]: print_classname = print_classname
Hoặc, tương đương
def print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
Cũng có thể thêm phương thức vào đối tượng kiểu “A”. Tuy nhiên, bạn cần xác định rằng thuộc tính “print_classname” của đối tượng là một phương thức để đảm bảo rằng nó sẽ nhận tham chiếu đến “self” dưới dạng tham số đầu tiên ngầm định khi nó được gọi
from types import MethodType def print_classname[a]: print a.__class__.__name__ class A[object]: pass # this assigns the method to the instance a, but not to the class definition a = A[] a.print_classname = MethodType[print_classname, a, A] # this assigns the method to the class definition A.print_classname = MethodType[print_classname, None, A]
Các phương thức cụ thể từ một lớp khác cũng có thể được thêm vào [không kế thừa mọi thứ khác] bằng cách thêm chức năng cơ bản của phương thức. Mặt khác, phương thức sẽ mong đợi một tham chiếu đến một thể hiện của lớp gốc dưới dạng tham số đầu tiên ngầm định
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]3 Bình luận
« Đó là mùa B[bq]RG
Chạy Matlab dưới dạng quy trình con Python »
3 phản hồi cho “Thêm phương thức vào lớp Python”
JJ nói. bài viết tuyệt vời. Có cách nào để thêm một phương thức vào một lớp khác trong Python 3 không?
tom nói. không chắc, nhưng tôi nghĩ bạn không thể vì khái niệm về phương thức *không ràng buộc* đã biến mất trong Python 3 [xem. ]…
Tôi có một mô hình
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 đại diện cho một bài tập có thể được đưa vào một bài kiểm tra bên trong ứng dụng LMS Django REST của tôiCác bài tập gói gọn một số logic như
- điểm cao nhất có thể đạt được cho bài tập này là gì?
- làm thế nào để bạn đánh giá một câu trả lời cho bài tập này?
- làm thế nào để bạn xác định xem bài tập có câu trả lời trống hay không?
Ví dụ, trong một câu hỏi/bài tập trắc nghiệm, giả sử có một mô hình
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
8 với thuộc tínhclass B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
9. Trong trường hợp này, những điều trên được thực hiện như sau- sự lựa chọn với số điểm tối đa
- điểm của lựa chọn đã chọn
- liệu một lựa chọn có được chọn hay không
Tôi muốn các bên thứ ba có thể mở rộng ứng dụng của mình và loại bỏ mô hình
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 [dự định là đối tượng dữ liệu] khỏi logic nghiệp vụ của một bài tậpCác bài tập có thuộc tính
0 xác định loại của chúng. Ngay bây giờ, các phương thức nhưclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
1,class Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
2 vàclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
3 nằm bên trong chính mô hình và chứa một loạtclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
4 để áp dụng các lựa chọn chính xác dựa trên giá trị của thuộc tínhclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
0class Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
Điều tôi muốn làm là tạo một lớp cơ sở trừu tượng
6 và kế thừa từ nó cho từng loại bài tập và triển khai các phương thức tương tự như mô tả ở trên. Sau đó,class Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
6 sẽ có mộtclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
8class Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
9 được sử dụng để khởi tạo và trả về lớp con chính xác mà các phương thức sẽ được gọi cho mộtclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7Để duy trì khả năng tương thích ngược và giao diện đơn giản, điều mà tôi đang cân nhắc thực hiện là tự động thêm các phương thức được khai báo trong
6 vào lớpclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7Giả sử
6 có một phương thức gọi làclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
1, sau đó tôi muốnclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 có một phương thức
1 thực hiện điều gì đó tương tự như thế nàyclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
def print_classname[a]: print a.__class__.__name__ class A[object]: print_classname = print_classname
9Tôi đã đọc rằng Django làm điều gì đó tương tự bằng cách sử dụng các bộ mô tả để thêm các mối quan hệ đảo ngược vào các mô hình
Làm thế nào tôi có thể đạt được một cái gì đó tương tự?
KenWhitesellTôi sẽ thừa nhận, tôi đang gặp khó khăn trong việc hiểu những gì bạn đang thực sự cố gắng đạt được ở đây
Tôi đoán cách tốt nhất để giải thích nó là. Tôi đang cố gắng ủy thác một số thao tác mà mô hình của tôi hiện đang thực hiện cho một lớp khác. Lý do cho điều đó là, trong khi việc mở rộng một mô hình là “khó” [ai đó muốn phát triển một tiện ích mở rộng cho ứng dụng của tôi sẽ không thể kế thừa từ mô hình của tôi, vì nó không trừu tượng và việc kế thừa từ nó sẽ gây ra việc tạo . Vì vậy, những gì tôi đang cố gắng làm là thiết kế một hệ thống phân cấp các lớp “logic nghiệp vụ” mà các phương thức của chúng có thể được gọi bởi lớp mô hình của tôi. Ai đó có thể phân lớp một trong các lớp đó, cập nhật một số loại “đăng ký” liên kết một
0 cụ thể với lớp con chính xác của lớp logic nghiệp vụ và chỉ nhận được hành vi mới cho một phiên bản mô hìnhclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 với
0 đó gọi các phương thức từ mô hìnhclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
KenWhitesellTrong Python, các hàm và phương thức là các đối tượng hạng nhất. Điều này có nghĩa là chúng có thể được gán trực tiếp giống như bất kỳ thuộc tính nào khác
Tôi hiểu điều đó, tôi đoán điều tôi đang cố gắng tìm ra là cách tốt nhất để tự động gán, cho mỗi phương thức trên lớp
6 của tôi, một phương thức có cùng tên với lớpclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7, phương thức này khởi tạo một
6 và gọi cùng một-class Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
KenWhitesellBạn cũng có sẵn nhiều tài sản thừa kế cho mình. Mô hình
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 của bạn có thể kế thừa trực tiếp phương thức
1 từ lớpclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
6class Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
Điều đó có thể hiệu quả, vấn đề là
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 của tôi không nên chỉ gọi một phương thức từ
6. Thay vào đó, phương thức phải được gọi trên một thể hiện của lớp con củaclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
6 và lớp con đó phụ thuộc vào giá trị của một thuộc tính [cụ thể làclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
0] của thể hiệnclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 tương ứng. Về cơ bản, tôi đang cố triển khai một số dạng gửi phương thức động, không chỉ trên lớp gọi mà là trên một số phân cấp lớp “có liên quan”Tôi nghĩ rằng tôi đang tiến gần hơn đến việc hiểu mục đích ở đây - nhưng tôi vẫn không chắc mình hiểu mục tiêu gốc là gì. [Tôi đang cố gắng hiểu điều này từ góc độ yêu cầu chứ không phải triển khai. ]
Những gì tôi nghĩ rằng tôi đang đọc là bạn đang tìm cách cung cấp một mô hình trong gói của mình
Bạn muốn người khác có thể mở rộng gói của bạn sao cho gói của bạn sử dụng các chức năng từ tiện ích mở rộng đó
Bạn sẽ xác định danh sách các chức năng có thể được mở rộng
Tập hợp cụ thể [hoặc tập hợp con] các chức năng đang được triển khai tùy thuộc vào người khác đó
Tôi có gần gũi không?
samuel-1Về cơ bản, tôi đang cố gắng triển khai một số dạng gửi phương thức động, không chỉ trên lớp gọi mà là trên một số phân cấp lớp "có liên quan"
Hãy nhớ rằng nếu
def print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
91 là một thể hiện của một số lớp, thìdef print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
92 giống nhưdef print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
93 và do đó,def print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
94 sẽ giống nhưdef print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
95Cũng lưu ý rằng bạn có sẵn để thay đổi hành vi mà không cần tạo bảng bổ sung
KenWhitesellNhững gì tôi nghĩ rằng tôi đang đọc là bạn đang tìm cách cung cấp một mô hình trong gói của mình
Bạn muốn người khác có thể mở rộng gói của bạn sao cho gói của bạn sử dụng các chức năng từ tiện ích mở rộng đó
Gần như—tôi muốn người khác có thể viết một gói và cài đặt nó vào ứng dụng của tôi [tất nhiên là ai đó sẽ chạy cài đặt ứng dụng của riêng họ], về cơ bản, họ có thể viết một phần bổ trợ cho ứng dụng của tôi
Ý tưởng như sau
- mỗi loại bài tập xác định [chúng ta hãy giới hạn bản thân trong phương pháp cụ thể này] một phương pháp
def print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
97. Đối với MCQ, phương thức này trả về điểm của lựa chọn đã chọn, đối với bài tập viết mã, phương thức này sẽ chạy bài tập và đếm các trường hợp kiểm tra đã vượt qua… bạn hiểu ý - người khác quyết định tạo một loại bài tập mới, chẳng hạn như “bài tập phương trình”. Dạng bài tập đó xác định một phương trình, nhận một câu trả lời bằng số, tính phương trình và kiểm tra xem câu trả lời đã cho có đúng không, i. e. đó là kết quả của phương trình
- để tích hợp loại bài tập mới, tôi muốn nhà phát triển phần bổ trợ có thể kế thừa từ
6, kế thừa [các] phương thức liên quan và hoàn thành nóclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
- các bài tập sẽ được xử lý thống nhất bởi ứng dụng của tôi, vì vậy trong một bài kiểm tra có chứa các loại bài tập hỗn hợp, hệ thống của tôi phải có khả năng, để tính toán, chẳng hạn, điểm tổng thể, chỉ cần lặp lại các bài tập và các câu trả lời đã cho và gọi
Tôi hy vọng tôi đã giải thích điều đó rõ ràng hơn trước đây—tôi hiểu điều này hơi giả tạo
KenWhitesellHiểu biết của tôi về các mô hình proxy là bạn có thể sử dụng chúng để có được hành vi nhất định cho các mô hình của mình, nhưng bạn phải chọn thủ công proxy mà bạn đang khởi tạo. Như tôi đã giải thích ở trên, tôi không muốn lớp đó trong ứng dụng của mình phải quyết định khởi tạo mô hình nào bằng cách xem
0 của phiên bản mô hìnhclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
samuel-1Tôi hy vọng tôi đã giải thích điều đó rõ ràng hơn tôi đã làm trước đây
Đó không phải là lời giải thích của bạn - mà là tôi đang cố gắng xoay quanh một lĩnh vực vấn đề mà tôi không quen thuộc
Tôi nghĩ rằng phản ứng hiện tại của tôi đối với điều này là tôi sẽ tách những “bộ giải quyết” này khỏi mô hình. Bạn đề cập rằng bạn không muốn tạo các bảng mới - bạn muốn tất cả các lớp này hoạt động với cùng một mô hình [các phiên bản khác nhau, nhưng cùng một lớp]
Sau đó, tôi sẽ chia các chức năng đó thành một hệ thống phân cấp lớp riêng biệt. Sau đó, quy trình đăng ký của bạn có thể bao gồm việc tạo các phiên bản của các lớp đó và gán chúng cho một “loại bài tập”. [Và nó có thể trực tiếp như một lệnh trong đó khóa là loại bài tập và giá trị là lớp. ]
Phương thức
from types import MethodType def print_classname[a]: print a.__class__.__name__ class A[object]: pass # this assigns the method to the instance a, but not to the class definition a = A[] a.print_classname = MethodType[print_classname, a, A] # this assigns the method to the class definition A.print_classname = MethodType[print_classname, None, A]
83 trên lớp cha có thể thực hiện logic đăng ký, ngăn không cho lớp con thực hiện việc nàySau đó, mô hình có thể tạo phiên bản của lớp phân giải đó và chuyển chính nó dưới dạng tham số sao cho các hàm có sẵn mô hình [hoặc các trường mong muốn] trên
from types import MethodType def print_classname[a]: print a.__class__.__name__ class A[object]: pass # this assigns the method to the instance a, but not to the class definition a = A[] a.print_classname = MethodType[print_classname, a, A] # this assigns the method to the class definition A.print_classname = MethodType[print_classname, None, A]
84Vì vậy, tôi quyết định giữ lại câu trả lời của mình cho đến khi tôi có đủ thời gian để triển khai bản phác thảo giải pháp, vì mã có thể nói rõ ràng hơn lời nói
Hãy tóm tắt lại vấn đề hiện tại
- Tôi có một mô hình
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 làm mẫu một câu hỏi/bài toán/bài tập để đưa vào bài kiểm tra. Có nhiều loại bài tập khác nhau, chẳng hạn như câu hỏi trắc nghiệm, bài tập lập trình, câu hỏi trả lời mở, v.v. - Tôi muốn có thể quản lý thống nhất các bài tập của mình, ví dụ: tôi muốn có thể truy vấn tất cả các loại bài tập cùng nhau và chèn các loại bài tập khác nhau vào cùng một bài kiểm tra
- Đồng thời, có một số điều nhất định về các bài tập cần được xử lý khác nhau tùy thuộc vào loại bài tập. Ví dụ, làm thế nào để chấm câu trả lời cho một bài tập?
- Các bên thứ ba có thể muốn tạo nhiều loại bài tập hơn trong tương lai và tôi không muốn họ phải thêm các nhánh if-else vào mã hiện có. Tôi muốn một giải pháp dễ dàng mở rộng
Đây là những gì tôi đã làm. Mô hình
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7 trông như thế nàyclass Exercise[models.Model]: """ An Exercise represents a question, coding problem, or other element that can appear inside of an exam. """ MULTIPLE_CHOICE = 0 OPEN_ANSWER = 1 JS = 2 ATTACHMENT = 3 PYTHON = 4 EXERCISE_TYPES = [ [MULTIPLE_CHOICE, "Multiple choice question"], [OPEN_ANSWER, "Open answer"], [JS, "JavaScript"], [ATTACHMENT, "Attachment"], [PYTHON, "Python"], ] course = models.ForeignKey[ Course, on_delete=models.PROTECT, related_name="exercises", ] exercise_type = models.PositiveSmallIntegerField[choices=EXERCISE_TYPES] text = models.TextField[blank=True] objects = ExerciseManager[] def get_logic[self]: from courses.logic.exercise_logic import ExerciseLogic return ExerciseLogic.from_exercise_instance[self]
Bây giờ, hãy xác định một lớp dữ liệu mô hình hóa việc gửi câu hỏi. Có một mô hình cụ thể trong ứng dụng của tôi, đại diện cho một bài tập được giao cho người dùng VÀ việc gửi nó VÀ đánh giá của giáo viên [điểm số, phản hồi, v.v. ]
Vì chúng ta sẽ làm việc bên trong một “lớp logic”, nên tôi quyết định không chuyển toàn bộ thể hiện của mô hình như hiện tại, và thay vào đó tạo một lớp chỉ gói gọn các trường liên quan
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
1Vì vậy, lớp này đã tạo ra một lớp định hướng giữa mô hình cơ bản và chỉ thể hiện sự phục tùng của một học sinh đối với một bài tập
Bây giờ vào những thứ nhiều thịt
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
2Đây là lớp cơ sở đóng gói logic cho một bài tập. Tôi sẽ tìm hiểu về cách thức hoạt động của phương thức
from types import MethodType def print_classname[a]: print a.__class__.__name__ class A[object]: pass # this assigns the method to the instance a, but not to the class definition a = A[] a.print_classname = MethodType[print_classname, a, A] # this assigns the method to the class definition A.print_classname = MethodType[print_classname, None, A]
87 một lát nữaChúng ta hãy xem một vài lớp con của lớp này
def print_classname[a]: print a.__class__.__name__ class A[object]: pass setattr[A, "print_classname", print_classname]
9Vì vậy, mỗi lớp con trong hệ thống phân cấp thực hiện logic khác nhau. Bây giờ, điều duy nhất còn lại là tự động lấy phân lớp chính xác tùy thuộc vào loại bài tập
Tôi đã xác định chức năng sau
from types import MethodType def print_classname[a]: print a.__class__.__name__ class A[object]: pass # this assigns the method to the instance a, but not to the class definition a = A[] a.print_classname = MethodType[print_classname, a, A] # this assigns the method to the class definition A.print_classname = MethodType[print_classname, None, A]
8Hiện tại, nó trả về một lệnh, nhưng tôi không muốn viết mã cứng vì trong tương lai, nó có thể làm một việc khác như tự động phát hiện các lớp logic
Vì vậy, từ một ví dụ về
class B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
7, bất cứ khi nào chúng tôi muốn đạt điểm tối đa có thể, chúng tôi sẽ thực hiệnfrom types import MethodType def print_classname[a]: print a.__class__.__name__ class A[object]: pass # this assigns the method to the instance a, but not to the class definition a = A[] a.print_classname = MethodType[print_classname, a, A] # this assigns the method to the class definition A.print_classname = MethodType[print_classname, None, A]
89. Điều này sẽ tra cứu tên đủ điều kiện của lớp conclass B[object]: def print_classname[self]: print self.__class__.__name__ # option 1 class A[object]: print_classname = B.print_classname.__func__ # option 2 class A[object]: pass setattr[A, "print_classname", B.print_classname.__func__]
70 chính xác cho loại bài tập, nhập động và khởi tạo nó, chuyển thể hiện bài tậpBạn nghĩ gì về phương pháp này?
Cá nhân tôi có cảm xúc lẫn lộn về nó—có vẻ như nó làm được những gì tôi muốn, nhưng tôi e rằng nó có thể hơi phức tạp và tôi có thể đang trang bị quá mức cho nhu cầu hiện tại của mình và không nghĩ đến các trường hợp sử dụng có thể xảy ra trong tương lai'
Python cho phép thêm các phương thức động như thế nào?
Thêm động các phương thức trong Python .từ các loại nhập MethodType class Person[object]. def __init__[bản thân, tên]. bản thân. .lớp Người [đối tượng]. def __init__[bản thân, tên]. bản thân. .lớp UpperList [danh sách]. vượt qua def to_upper[self]. cho chỉ mục, mục trong liệt kê [bản thân]. bản thân [chỉ mục] = mục__ thêm __ hoạt động như thế nào?
Phương thức __add__[] trong Python chỉ định điều gì sẽ xảy ra khi bạn gọi + trên hai đối tượng . Khi bạn gọi obj1 + obj2, về cơ bản bạn đang gọi obj1. __add__[obj2]. Điều này hoạt động, bởi vì int thực hiện phương thức __add__[] đằng sau hậu trường.__ phương thức __ trong Python là gì?
__getitem__ được dùng để lấy một mục từ thuộc tính của thực thể được gọi . __getitem__ thường được sử dụng với các thùng chứa như danh sách, tuple, v.v. Phương thức __setitem__ được sử dụng để đặt mục thành một chỉ mục cụ thể của thuộc tính của phiên bản được gọi. Tương tự như __getitem__, __setitem__ cũng được sử dụng với các thùng chứa.__ mới __ trong Python là gì?
Python __new__[] là phương thức khởi tạo kiểm soát việc tạo phiên bản mới . Nó được gọi đầu tiên và nó trả về một thể hiện của lớp mới. Python __init__[] là phương thức khởi tạo để thiết lập các thuộc tính [i. e. , trạng thái] của phiên bản mới được tạo. Nó được gọi sau khi tạo và không trả về gì cả, tôi. e. , Không có.