2010-10-22 37 views
5
def foo(a, b, c = 0): 
    return a+b 

Tôi có hàng tá chức năng như 'foo', tất cả đều có số và tên đối số khác nhau. Có một cách phổ biến mà tôi có thể nhận được các giá trị trả lại của các chức năng này và làm chỉ là một hoạt động thêm duy nhất như pformat cho họ?Có thể sửa đổi giá trị trả về của một hàm không định nghĩa hàm mới trong python không?

Có, tôi chỉ có thể tạo ra một chức năng mới như sau:

func = ... # func can be got using getattr by name 
def wrapper(*arg, **kw): 
    data = func(*arg, **kw) 
    return pprint.pformat(data) 
return wrapper 

Nhưng sau đó các chức năng mới 'wrapper' khác với cái cũ 'func', ví dụ, trong số lập luận, 'wrapper 'chỉ có 2 args -' arg 'và' kw ', nhưng' func 'có thể có nhiều arg, như' a ',' b ',' c '.

Tôi chỉ muốn chơi với giá trị trả lại, mọi thứ khác sẽ vẫn còn, có thể không?

Cảm ơn!

Cập nhật Cuối cùng vấn đề này đã được giải quyết bằng decorator mô-đun và các bản vá sau:

--- /home/jaime/cache/decorator-3.2.0/src/decorator.py 2010-05-22 23:53:46.000000000 +0800 
+++ decorator.py 2010-10-28 14:55:11.511140589 +0800 
@@ -66,9 +66,12 @@ 
      self.name = '_lambda_' 
      self.doc = func.__doc__ 
      self.module = func.__module__ 
-   if inspect.isfunction(func): 
+   if inspect.isfunction(func) or inspect.ismethod(func): 
       argspec = inspect.getargspec(func) 
       self.args, self.varargs, self.keywords, self.defaults = argspec 
+    if inspect.ismethod(func): 
+     self.args = self.args[1:] # Remove the useless 'self' arg 
+     argspec = inspect.ArgSpec(self.args, self.varargs, self.keywords, self.defaults) 
       for i, arg in enumerate(self.args): 
        setattr(self, 'arg%d' % i, arg) 
       self.signature = inspect.formatargspec(

vá này cho phép bạn để trang trí các phương pháp bị chặn, nó chỉ ném đầu tiên 'tự' lập luận đi, sử dụng decorator.decorator giữ nguyên, không tìm thấy hiệu ứng xấu ngay bây giờ.

mã ví dụ:

def __getattr__(self, attr): 
    def pformat_wrapper(f, *args, **kw): 
     data = f(*args, **kw) 
     return pprint.pformat(data, indent = 4) 

    method = getattr(self.ncapi, attr) 
    return decorator(pformat_wrapper, method) # Signature preserving decorating 





[email protected]:~/bay/dragon.testing/tests$ python 
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import decorator 
>>> class A: 
... def f(self): 
...  pass 
... 
>>> a = A() 
>>> a.f 
<bound method A.f of <__main__.A instance at 0xb774a20c>> 
>>> def hello(f, *args, **kw): 
...  print 'hello' 
...  return f(*args, **kw) 
... 
>>> f1 = decorator.decorator(hello, a.f) 
>>> f1() 
hello 
>>> 
+0

Phương pháp này có quá tải không? – Tauquir

+0

BTW Python không hỗ trợ quá tải phương thức. – Tauquir

+0

Thay đổi các hàm của bạn để thay thế các giá trị có thể sử dụng bằng các chuỗi 'pprint.pformat' thực sự là một ý tưởng thực sự tồi (tm). Đừng. Do. Nó. –

Trả lời

3

Về vấn đề của bạn:

"Nhưng sau đó các chức năng mới 'wrapper' khác với cái cũ 'func', ví dụ, >> trong số lập luận, 'wrapper' chỉ có 2 args - 'arg' và 'kw', nhưng 'func' có thể có nhiều >> ​​args, như 'a', 'b', 'c'. "

bạn có thể sử dụng các mô-đun decorator cho phép bạn tạo ra một trang trí chữ ký bảo quản.

+0

+1 để đề cập đến mô-đun trang trí. Nó thực sự mạnh mẽ. Ngoài ra [Venusian] (http://pypi.python.org/pypi/venusian) có thể hữu ích khi giao dịch với người trang trí. –

+0

mô-đun trang trí hầu như giải quyết được vấn đề, nhưng có vẻ như nó không hoạt động với các phương thức bị ràng buộc hoặc không ràng buộc. "Hơn nữa, chú ý rằng bạn có thể trang trí một phương thức, nhưng chỉ trước khi trở thành một phương thức bị ràng buộc hoặc không ràng buộc, tức là bên trong lớp ....", vì vậy nó vô ích nếu bạn muốn trang trí một số phương thức của một lớp mà không sửa đổi mã nguồn của nó theo như tôi thấy. – jaimechen

2

trang trí.

from functools import wraps 
def pformat_this(someFunc): 
    @wraps(someFunc) 
    def wrapper(*arg, **kw): 
     data = someFunc(*arg, **kw) 
     return pprint.pformat(data) 
    return wrapper 


@pformat_this 
def foo(a, b, c = 0): 
    return a+b 
+0

Không nên là '@ pformat_this'? –

+2

@ S.Loot: functools.wrap không phải là một trang trí bảo quản chữ ký, nó chỉ bảo toàn _ _name_ _ và _ _doc_ _ – mouad

2

Trang trí cơ bản giống như những gì bạn không muốn.

Bắt tò mò, tôi đã xem xét điều này cho trăn 2.7 và thấy rằng có a wealth of meta information available for user defined functions trong Các loại có thể gọi -> Các hàm do người dùng định nghĩa. Thật không may, không có gì về giá trị trả về.

Ngoài ra còn có kiểu nội bộ bạn có thể truy cập thông qua hàm, đối tượng mã, trên the same page, trong Loại nội bộ -> Đối tượng mã. Mặc dù các kiểu nội bộ này về cơ bản được cung cấp không có lời hứa cho sự ổn định API, dường như không có bất cứ điều gì có thể ghi được đối với giá trị trả về ở đó.

Tôi có cảm giác rằng nếu có bất cứ điều gì bạn có thể làm trực tiếp, nó sẽ ở đây. Hy vọng rằng ai đó có may mắn hơn cho bạn.

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