2009-11-08 31 views
29

Tôi muốnPython: @staticmethod với @property

Stats.singleton.twitter_count += 1 

và tôi nghĩ tôi có thể làm

class Stats: 
    singleton_object = None 

    @property 
    @staticmethod 
    def singleton(): 
     if Stats.singleton_object: 
      return Stats.singleton_object 
     Stats.singleton_object = Stats() 
     return Stats.singleton() 

Nhưng nó ném một ngoại lệ:

>>> Stats.singleton.a = "b" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'property' object has only read-only attributes (assign to .a) 
+2

nơi 'singleton_object' được xác định? – tonfa

+3

ở đâu là 'self' được định nghĩa? – tonfa

+2

xác định "không hoạt động" – u0b34a0f6ae

Trả lời

8

Singletons là vô nghĩa trong python.

class A: 
    class_var = object() 

# two objects 
a, b = A(), A() 

# same var everywhere 
assert a.class_var is b.class_var is A.class_var 

Python của int s là differnt từ đơn giản object s, vì vậy nó không phải luôn luôn là đơn giản. Nhưng với mục đích của bạn, điều này có vẻ là đủ:

class Stats: 
    twitter_count = 0 

Stats.twitter_count +=1 
Stats.twitter_count +=1 
assert Stats.twitter_count == 2 
+0

Tôi có một chút của một cốt truyện, trong đó tôi muốn có một AppEngine db.Mô hình đối tượng là một singleton (chỉ một đối tượng Thống kê trong cơ sở dữ liệu). Vì vậy, tôi cần phải có ít nhất một thể hiện trong bộ nhớ. –

+1

Tôi không hiểu. Khi bạn có một DB phía sau, tất cả các cá thể đã chia sẻ cùng một trạng thái, trạng thái của một hàng trong DB của bạn. Hai trường hợp có thể không giống nhau, nhưng bất kỳ ORM nào xứng đáng với tên đó sẽ đảm bảo rằng việc thay đổi cũng sẽ thay đổi tên khác. –

+32

Trên tất cả các bạn nghe mọi người nói rằng phương pháp tĩnh và đơn là vô nghĩa trong Python, yadda, yadda. Đó là tào lao. Singleton là một mẫu hình hợp lệ, cần thiết. Những gì "chúng tôi" cộng đồng lập trình lớn hơn muốn biết là "làm thế nào" chúng ta có nghĩa vụ phải làm điều đó "đúng cách". Bất kỳ câu trả lời nào không trả lời trực tiếp, tôi nghĩ, vô ích. Tôi, đối với một, đang bối rối về vấn đề này. :-) Cứu giúp! – 010110110101

6

phương pháp tĩnh không có ý nghĩa trong Python. Đó là bởi vì họ không làm gì mà các phương thức lớp không thể, và là các phương thức lớp dễ dàng hơn để mở rộng trong tương lai (khi nhiều phương thức lớp sử dụng lẫn nhau).

Điều bạn cần chỉ đơn giản là thuộc tính phương thức lớp.

Tôi có thuộc tính phương thức lớp từ mã của tôi tại đây. Nó chỉ là chỉ đọc, đó là tất cả những gì tôi cần (vì vậy phần còn lại là một bài tập cho người đọc):

class ClassProperty (property): 
    """Subclass property to make classmethod properties possible""" 
    def __get__(self, cls, owner): 
     return self.fget.__get__(None, owner)() 

# how I would use it 
class Stats: 
    singleton_object = None 
    @ClassProperty 
    @classmethod 
    def singleton(cls): 
     if cls.singleton_object is None: 
      cls.singleton_object = cls() 
     return cls.singleton_object 
+3

Tôi không nghĩ rằng có một câu trả lời cho 'bài tập cho người đọc' của bạn; phương thức __set__ của một bộ mô tả dữ liệu không được gọi khi bạn đang tìm kiếm một lớp. Các ràng buộc chỉ được thay đổi. –

+23

-1: phương pháp tĩnh là một công cụ hữu ích và có giá trị. – Reid

49

Người dùng kaizer.se đã lên một điều gì đó như câu hỏi ban đầu. Tôi lấy nó một bước xa hơn về sự đơn giản, vì vậy mà nó bây giờ chỉ cần một trang trí duy nhất:

class classproperty(property): 
    def __get__(self, cls, owner): 
     return classmethod(self.fget).__get__(None, owner)() 

Cách sử dụng:

class Stats: 
    _current_instance = None 

    @classproperty 
    def singleton(cls): 
     if cls._current_instance is None: 
      cls._current_instance = Stats() 
     return cls._current_instance 

Như đã nói, cách này tạo ra một singleton không phải là một tốt mẫu thiết kế; nếu điều đó phải được thực hiện, một nhà máy metaclass là một cách tốt hơn để làm điều đó. Tôi đã rất vui mừng về triển vọng của một tài sản lớp học, vì vậy, có nó được.

1

Tiếp theo kịp với những gì KyleAlanHale đã viết:

dụ của ông hoạt động tuyệt vời, cho đến khi bạn cố gắng và làm:

Stats.singleton = 5 

này sẽ không cung cấp cho bạn một lỗi, nó sẽ ghi đè lên các chức năng, do đó khi bạn gõ tiếp theo

single = Stats.singleton 
print single 

bạn sẽ nhận được

5 

Tôi nghĩ bạn nên sử dụng câu trả lời của Kyle mà không cần trang trí @classproperties.

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