2010-03-23 34 views
9

Làm cách nào để ghi đè lên một phương thức đặc biệt của lớp học?Lớp ghi đè của Python (không phải ví dụ) Các phương pháp đặc biệt

Tôi muốn có thể gọi phương thức __str__() của lớp mà không cần tạo cá thể. Ví dụ:

class Foo: 
    def __str__(self): 
     return 'Bar' 

class StaticFoo: 
    @staticmethod 
    def __str__(): 
     return 'StaticBar' 

class ClassFoo: 
    @classmethod 
    def __str__(cls): 
     return 'ClassBar' 

if __name__ == '__main__': 
    print(Foo) 
    print(Foo()) 
    print(StaticFoo) 
    print(StaticFoo()) 
    print(ClassFoo) 
    print(ClassFoo()) 

sản xuất:

<class '__main__.Foo'> 
Bar 
<class '__main__.StaticFoo'> 
StaticBar 
<class '__main__.ClassFoo'> 
ClassBar 

nên là:

Bar 
Bar 
StaticBar 
StaticBar 
ClassBar 
ClassBar 

Thậm chí nếu tôi sử dụng @staticmethod hoặc @classmethod các __str__ vẫn còn sử dụng được xây dựng trong Python định nghĩa cho __str__. Nó chỉ hoạt động khi nó là Foo().__str__() thay vì Foo.__str__().

+0

-1: "gọi phương thức' __str __() 'của lớp mà không tạo một thể hiện". Phá vỡ mọi sự hiểu biết bất cứ ai có đối tượng là gì. Vui lòng đừng làm vậy. Nó làm cho chương trình hoàn toàn vi phạm những kỳ vọng cơ bản nhất của chúng tôi. –

+5

Tôi không đồng ý. Nếu bạn gọi str (MyClass) thì không có lý do nào bạn mong đợi nó hoạt động như thể bạn vừa gọi str (myClassObject). Đó là, không có kỳ vọng cơ bản để bắt đầu với. Tôi nghi ngờ anh ta muốn tạo ra một lớp tĩnh và không bao giờ có ý định tạo ra bất kỳ trường hợp nào của nó. –

Trả lời

17

Phương thức đặc biệt __str__ được xác định trong một lớp chỉ hoạt động cho các trường hợp của lớp đó, để có hành vi khác nhau đối với đối tượng lớp bạn sẽ phải thực hiện nó trong metaclass của lớp đó. (Python 2,5)

class Meta(type): 
    def __str__(self): 
     return "Klass" 

class A(object): 
    __metaclass__ = Meta 

    def __str__(self): 
     return "instance" 

print A 
print A() 

đầu ra:

Klass 
instance 
+1

Tôi đã phải sử dụng cú pháp py3 mới của lớp C (metaclass = M): ... nhưng nó hoạt động! –

1

Tại sao bạn muốn lạm dụng ý nghĩa của __str__? Phương thức đó được dành riêng cho ý nghĩa "trả về một biểu diễn chuỗi là ví dụ này".

Nếu bạn muốn hàm trả về một chuỗi tĩnh, sẽ tốt hơn nếu có hàm riêng biệt không nằm trong một lớp.

Nếu bạn muốn một hàm tạo trả về một chuỗi mới, đặt tên cho nó là một cái gì đó khác để nó không bị che khuất tên __str__ được đặt trước.

0

Tôi không chắc chắn những gì bạn đang cố gắng để làm, chính xác. Hãy để tôi thêm một chút thông tin ngẫu nhiên.

Đầu tiên, thêm lớp này:

class FooNew(object): 
def __str__(self): 
    return 'Fubar' 

In này thay vì:

if __name__ == '__main__': 
    print "You are calling type for an old style class" 
    print(Foo) 
    print(type.__str__(Foo)) 
    print(Foo()) 
    print("But my Python 2.6 didn't match your output for print(Foo)") 
    print("You are calling object.str() for a new style class") 
    print(FooNew) 
    print(object.__str__(FooNew)) 
    print(FooNew()) 
    print("Why do you want to change this?") 

Để có được điều này:

You are calling type for an old style class 
__main__.Foo 
<class __main__.Foo at 0xb73c9f5c> 
Bar 
But my Python 2.6 didn't match your output for print(Foo) 
You are calling object.str() for a new style class 
<class '__main__.FooNew'> 
<class '__main__.FooNew'> 
Fubar 
Why do you want to change this? 

Bạn có hoàn toàn chắc chắn bạn không muốn gọi một classmethod?

Các vấn đề liên quan