Như đã đề cập ở trên, nếu bạn muốn giữ mọi thứ đơn giản, chỉ cần sử dụng thuộc tính ví dụ: _ordering
, theo cách thủ công theo dõi đặt hàng. Nếu không, đây là một cách tiếp cận metaclass (giống như một Django sử dụng), mà tạo ra một thuộc tính đặt hàng tự động.
ghi thứ tự ban đầu
Lớp học không theo dõi các Trật tự của các thuộc tính. Tuy nhiên, bạn có thể theo dõi thứ tự các trường thể hiện được tạo ra. Đối với điều đó, bạn sẽ phải sử dụng lớp của riêng bạn cho các trường (không phải int). Lớp này theo dõi bao nhiêu trường hợp đã được tạo và mỗi cá thể sẽ ghi lại vị trí của nó. Đây là cách bạn sẽ làm điều đó ví dụ của bạn (lưu trữ số nguyên):
class MyOrderedField(int):
creation_counter = 0
def __init__(self, val):
# Set the instance's counter, to keep track of ordering
self.creation_counter = MyOrderedField.creation_counter
# Increment the class's counter for future instances
MyOrderedField.creation_counter += 1
Tạo một thuộc tính ordered_items
tự động
Bây giờ các lĩnh vực của bạn có một số có thể được sử dụng để ra lệnh cho họ, cha mẹ của bạn lớp học cần phải sử dụng bằng cách nào đó. Bạn có thể làm điều này theo nhiều cách khác nhau, nếu tôi nhớ chính xác, Django sử dụng Metaclasses để làm điều này, điều này hơi hoang dã đối với một lớp đơn giản.
class BaseWithOrderedFields(type):
""" Metaclass, which provides an attribute "ordered_fields", being an ordered
list of class attributes that have a "creation_counter" attribute. """
def __new__(cls, name, bases, attrs):
new_class = super(BaseWithOrderedFields, cls).__new__(cls, name, bases, attrs)
# Add an attribute to access ordered, orderable fields
new_class._ordered_items = [(name, attrs.pop(name)) for name, obj in attrs.items()
if hasattr(obj, "creation_counter")]
new_class._ordered_items.sort(key=lambda item: item[1].creation_counter)
return new_class
Sử dụng metaclass này
Vì vậy, làm thế nào để bạn sử dụng này? Trước tiên, bạn cần sử dụng lớp MyOrderedField
mới của chúng tôi khi xác định thuộc tính của bạn.lớp mới này sẽ theo dõi thứ tự mà các lĩnh vực đã được tạo ra:
class Ordered(object):
__metaclass__ = BaseWithOrderedFields
x = MyOrderedField(0)
z = MyOrderedField(0)
b = MyOrderedField(0)
a = MyOrderedField(0)
Sau đó, bạn có thể truy cập vào các lĩnh vực ra lệnh tự động tạo ra thuộc tính của chúng tôi ordered_fields
:
>>> ordered = Ordered()
>>> ordered.ordered_fields
[('x', 0), ('z', 0), ('b', 0), ('a', 0)]
Hãy để thay đổi điều này để một lệnh dict hoặc chỉ cần trả lại tên hoặc bất cứ điều gì bạn cần. Ngoài ra, bạn có thể xác định một lớp trống với __metaclass__
và kế thừa từ đó.
Không sử dụng quyền này!
Như bạn có thể thấy, cách tiếp cận này hơi phức tạp và có thể không phù hợp với hầu hết các tác vụ hoặc nhà phát triển python. Nếu bạn là người mới bắt đầu với python, bạn có thể sẽ dành nhiều thời gian và công sức để phát triển metaclass của bạn hơn bạn sẽ có nếu bạn chỉ định đặt hàng theo cách thủ công. Xác định đặt hàng của bạn bằng tay là hầu như luôn luôn sẽ là cách tiếp cận tốt nhất. Django tự động làm điều đó vì mã phức tạp bị ẩn khỏi nhà phát triển cuối và Django được sử dụng thường xuyên hơn chính nó được viết/duy trì. Vì vậy, chỉ khi bạn đang phát triển một khung cho các nhà phát triển khác, thì metaclasses có thể hữu ích cho bạn.
phương pháp, tài sản vv được lưu dưới dạng từ điển trong các đối tượng, và từ điển là theo định nghĩa thứ tự. Bạn đang cố gắng đạt được điều gì (hoặc tốt hơn, tại sao)? –
Bạn cần Python 3 để làm điều này mà không cần hack: http://stackoverflow.com/a/4460565/821378 –