Person.name
là một thể hiện của một số nhập với phương thức tùy chỉnh __eq__
. Trong khi __eq__
thường trả về một giá trị boolean (ish), nó thực sự có thể trả lại bất cứ điều gì bạn muốn, bao gồm một lambda. Xem Python special method names để biết thêm về điều này và các phương pháp liên quan.
Có lẽ khó hiểu nhất/gây hiểu lầm là một phần của việc này (đặc biệt là nếu bạn đang sử dụng các ngôn ngữ OO khác như Java) là Person.name
và person.name
(nơi person
là một thể hiện của Person
) không cần phải có bất kỳ mối quan hệ với lẫn nhau. Ví dụ:
class Person(object):
name = "name of class"
def __init__(self):
self.name = "name of instance"
person = Person()
print Person.name
print person.name
này sẽ in:
name of class
name of instance
Lưu ý rằng thuộc tính lớp chỉ được thiết lập trong cơ thể lớp, trong khi tài sản chẳng hạn được thiết lập trong phương pháp __init__
.
Trong trường hợp của bạn, bạn nên đặt Person.name
đến đối tượng với tùy chỉnh __eq__
phương thức trả về một lambda, một cái gì đó như thế này:
class LambdaThingy(object):
def __init__(self, attrname):
self.__attrname = attrname
def __eq__(self, other):
return lambda x: getattr(x, self.__attrname) == other
class Person(object):
name = LambdaThingy('name')
def __init__(self, name):
self.name = name
equals_fred = Person.name == "Fred"
equals_barney = Person.name == "Barney"
fred = Person("Fred")
print equals_fred(fred)
print equals_barney(fred)
in này:
True
False
Điều này chắc chắn là ốp cạnh của "quá thông minh", vì vậy tôi sẽ rất thận trọng về việc sử dụng điều này trong mã sản xuất. Một lambda rõ ràng có lẽ sẽ rõ ràng hơn rất nhiều đối với các nhà bảo trì trong tương lai, ngay cả khi nó có một chút chi tiết hơn.
Nguồn
2009-05-04 21:19:20
Quá tải Java và toán tử ... không nghĩ nó sẽ trở thành hiện thực. Ở phía bên kia, có thể bạn đã đúng. – Geo
Odd .... Chấp nhận câu trả lời "đoán" khi câu trả lời khác dựa trên mã nguồn thực tế trong Storm. –
xin lỗi, nhưng tôi đoán là "đủ nhanh" :-) PS bạn nói đúng, rất kỳ quặc! – dfa