Tôi đang tạo một ứng dụng Django sử dụng một số thừa kế trong mô hình của nó, chủ yếu là vì tôi cần gán tất cả mọi thứ cho UUID và tham chiếu để tôi biết lớp đó là gì. Dưới đây là một phiên bản đơn giản của lớp cơ sở:Thừa kế và chức năng nhà máy trong Python và Django
class BaseElement(models.Model):
uuid = models.CharField(max_length=64, editable=False, blank=True, default=lambda:unicode(uuid4()))
objmodule = models.CharField(max_length=255, editable=False, blank=False)
objclass = models.CharField(max_length=255, editable=False, blank=False)
class ChildElement(BaseElement):
somefield = models.CharField(max_length=255)
Tôi muốn chắc chắn rằng objmodule, objclass, và uuid được thiết lập tự động. Tôi đã học được từ this post rằng đó là một ý tưởng tồi để làm điều đó bằng cách viết constructor của riêng tôi, và rằng tôi tốt hơn off viết một chức năng nhà máy. Vì vậy, bây giờ BaseElement và ChildElement của tôi trông giống như sau:
class BaseElement(models.Model):
uuid = models.CharField(max_length=64, editable=False, blank=True, default=lambda:unicode(uuid4()))
objmodule = models.CharField(max_length=255, editable=False, blank=False)
objclass = models.CharField(max_length=255, editable=False, blank=False)
def set_defaults(self):
self.objmodule = unicode(self.__class__.__module__)
self.objclass = unicode(self.__class__.__name__)
self.uuid = unicode(uuid4())
class ChildElement(BaseElement):
somefield = models.CharField(max_length=255)
@staticmethod
def create(*args, **kwargs):
ce = ChildElement(*args, **kwargs)
ce.set_defaults()
return ce
Tác phẩm này. Tôi có thể gọi ChildElement.create(somefield="foo")
và tôi sẽ nhận được một đối tượng thích hợp với các trường uuid
, objmodule
và objclass
được đặt chính xác. Tuy nhiên, khi tôi đi qua và tạo thêm các lớp như ChildElement2
và ChildElement3
, tôi thấy rằng tôi đang chèn chính xác cùng một chức năng nhà máy tĩnh. Điều này làm phiền tôi vì mã trùng lặp là xấu.
Với phương pháp thông thường, tôi chỉ cần chèn hàm nhà máy create
vào BaseElement
, tuy nhiên, tôi không thể làm điều đó ở đây vì tôi không có tay cầm (vì chưa được tạo) để nhận thông tin về lớp của đối tượng đã gọi phương thức.
Có cách nào mà tôi có thể di chuyển nhà máy này vào lớp BaseElement
vì vậy tôi không cần phải sao chép mã này ở khắp mọi nơi và vẫn có nó để nó tự động cài đặt các giá trị của uuid
, objmodule
, và objclass
?
Đó chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn đã nhắc tôi về '@ classmethod'. Nó không phải cái gì tôi sử dụng rất thường xuyên. – Pridkett
Trong Python, hiếm khi có trường hợp sử dụng tốt cho '@ staticmethod' - đó là trường hợp mà bạn có thể nên sử dụng ít thường xuyên hơn, nếu có. Thường thì nếu một cái gì đó không phải là một '@ classmethod' nó là thích hợp hơn như là một chức năng cấp cao nhất đơn giản trong một mô-đun. –