2012-02-12 10 views
7

Mã nguồn cho lớp trang trí nằm ở đâu trong mã nguồn python. Cụ thể là tôi đang gặp khó khăn khi tìm các tập tin chính xác nó được xác định trong phiên bản 2.7.2Vị trí của @classmethod

Trả lời

11

Tôi không trả lời những gì bạn hỏi - nhưng dưới đây cho thấy những gì có thể là một trang trí tương đương với classmethod, viết bằng Python Pure - kể từ khi một trong mã nguồn là trong C, bên trong Python-2.7.2/Objects/funcobject.c như Mishna đặt trong câu trả lời của mình. Vì vậy, ý tưởng về phương pháp lớp là sử dụng cơ chế "mô tả", như được mô tả trong Python's data model - và làm cho nó để phương thức __get__ trả về một đối tượng hàm khi được gọi, sẽ gọi phương thức gốc với phương thức đầu tiên Lập luận điền sẵn:

class myclassmethod(object): 
    def __init__(self, method): 
     self.method = method 
    def __get__(self, instance, cls): 
     return lambda *args, **kw: self.method(cls, *args, **kw) 

Và trên Python console:

>>> class MyClass(object): 
...  @myclassmethod 
...  def method(cls): 
...   print cls 
... 
>>> 
>>> m = MyClass() 
>>> m.method() 
<class '__main__.MyClass'> 
>>> 

* EDIT - cập nhật *

O.P. tiếp tục hỏi "Nếu tôi muốn người trang trí cũng chấp nhận một tham số thì định dạng thích hợp cho init là gì? "-

Trong trường hợp đó không chỉ là __init__ phải được thay đổi - trang trí chấp nhận tham số cấu hình thực sự được gọi là" hai giai đoạn "- chú thích đầu tiên chú thích tham số và trả về cuộc gọi thứ hai chỉ chấp nhận các chức năng mà thực sự sẽ được trang trí

có một số cách để làm điều đó - nhưng tôi nghĩ đơn giản nhất là phải có một hàm trả về lớp trên, như trong:.

def myclasmethod(par1, par2, ...): 
    class _myclassmethod(object): 
     def __init__(self, method): 
      self.method = method 
     def __get__(self, instance, cls): 
      # make use of par1, par2,... variables here at will 
      return lambda *args, **kw: self.method(cls, *args, **kw) 
    return _myclassmethod 
+1

Nếu tôi muốn người trang trí cũng chấp nhận một đoạn đồng hồ nào sẽ là định dạng thích hợp cho init? – user1200501

+0

có thể \ _ \ _ gọi \ _ \ _ được sử dụng thay vì \ _ \ _ nhận \ _ \ _? – DiogoNeves

+0

ok, sau khi đọc một chút về mô tả nó có ý nghĩa bây giờ :) – DiogoNeves

9
tar -zxf Python-2.7.2.tgz 
vim Python-2.7.2/Objects/funcobject.c 

... 
589 /* Class method object */ 
590 
591 /* A class method receives the class as implicit first argument, 
592 just like an instance method receives the instance. 
593 To declare a class method, use this idiom: 
594 
595  class C: 
596  def f(cls, arg1, arg2, ...): ... 
597  f = classmethod(f) 
598 
599 It can be called either on the class (e.g. C.f()) or on an instance 
600 (e.g. C().f()); the instance is ignored except for its class. 
601 If a class method is called for a derived class, the derived class 
602 object is passed as the implied first argument. 
603 
604 Class methods are different than C++ or Java static methods. 
605 If you want those, see static methods below. 
606 */ 
... 
+0

Cảm ơn cho đúng vị trí của lớp – user1200501