2012-08-02 28 views
5

Thực ra tiêu đề không phản ánh chính xác câu hỏi tôi muốn hỏi. Mục đích của tôi là như thế này: Tôi đang viết một số chức năng âm mưu bằng cách sử dụng matplotlib. Tôi có một loạt các chức năng dành cho mục đích vẽ đồ thị khác nhau. như line_plot() cho các dây chuyền, bar_plot() cho thanh, vv Ví dụ:sử dụng trang trí python để tự động thay thế hàm giá trị mặc định đối số?

import matplotlib.pyplot as plt 
def line_plot(axes=None,x=None,y=None): 
    if axes==None: 
     fig=plt.figure() 
     axes=fig.add_subplot(111) 
    else: 
     pass 
    axes.plot(x,y) 

def bar_plot(axes=None,x=None,y=None): 
    if axes==None: 
     fig=plt.figure() 
     axes=fig.add_subplot(111) 
    else: 
     pass 
    axes.bar(left=x,height=y) 

Tuy nhiên, vấn đề là, đối với mỗi chức năng đó là định nghĩa, tôi phải lặp lại một phần mã này:

if axes==None: 
     fig=plt.figure() 
     axes=fig.add_subplot(111) 
    else: 
     pass 

Có cách nào giống như bằng cách sử dụng một trang trí, mà tôi có thể áp dụng trước khi định nghĩa của chức năng âm mưu, mà sẽ làm các phần lặp đi lặp lại của mã tự động? Vì vậy tôi không phải lặp lại chúng mỗi lần.

một lựa chọn có thể là xác định một chức năng như thế này:

def check_axes(axes): 
    if axes==None: 
     fig=plt.figure() 
     axes=fig.add_subplot(111) 
     return axes 
    else: 
     return axes 

Sau đó, các ví dụ sẽ như thế nào:

import matplotlib.pyplot as plt  
def line_plot(axes=None,x=None,y=None): 
    axes=check_axes(axes) 
    axes.plot(x,y) 

def bar_plot(axes=None,x=None,y=None): 
    axes=check_axes(axes) 
    axes.bar(left=x,height=y) 

Nhưng Có/sạch/cách pythonic hơn tốt hơn? Tôi đoán tôi có thể sử dụng một trang trí nhưng không tìm ra. ai có thể đưa ra một số ý tưởng?

Cảm ơn !!

+2

Tôi nghĩ giải pháp cuối cùng của bạn khá tốt. Các hàm là các cách hiệu quả, đã được chứng minh để cấu trúc mã. Tôi nghi ngờ một người trang trí sẽ làm phức tạp những thứ không cần thiết. –

+0

Có lẽ bạn có thể tạo một lớp trục với bài kiểm tra của bạn ở init – zenpoy

Trả lời

7

Dưới đây là làm thế nào để làm điều đó với một trang trí:

import matplotlib.pyplot as plt  

def check_axes(plot_fn): 
    def _check_axes_wrapped_plot_fn(axes=None, x=None, y=None): 
     if not axes: 
      fig = plt.figure() 
      axes = fig.add_subplot(111) 
      return plot_fn(axes, x, y) 
     else: 
      return plot_fn(axes, x, y) 
    return _check_axes_wrapped_plot_fn 

@check_axes 
def line_plot(axes, x=None, y=None): 
    axes.plot(x, y) 

@check_axes 
def bar_plot(axes, x=None, y=None): 
    axes.bar(left=x, height=y) 

Cách hoạt động: cú pháp @check_axes định nghĩa lại tên của chức năng trang trí, ví dụ line_plot là một chức năng mới được tạo bởi trang trí, tức là _check_axes_wrapped_plot_fn. Chức năng "bọc" này xử lý logic kiểm tra axes và sau đó gọi hàm lô ban đầu.

Nếu bạn muốn check_axes để có thể trang trí bất kỳ chức năng cốt truyện mà phải mất một axes như là đối số đầu tiên của mình, không chỉ những điều đó cũng chỉ mất xy đối số, bạn có thể sử dụng * cú pháp tiện dụng Python cho danh sách đối số tùy ý:

def check_axes(plot_fn): 
    def _check_axes_wrapped_plot_fn(axes=None, *args): 
     if not axes: 
      fig = plt.figure() 
      axes = fig.add_subplot(111) 
      return plot_fn(axes, *args) # pass all args after axes 
     else: 
      return plot_fn(axes, *args) # pass all args after axes 
    return _check_axes_wrapped_plot_fn 

Bây giờ, bất kỳ điều này là "tốt hơn/sạch hơn/nhiều hơn Pythonic" có thể là vấn đề tranh luận và phụ thuộc vào ngữ cảnh lớn hơn.

Nhân tiện, với tinh thần là "nhiều Pythonic", tôi đã định dạng lại mã của bạn để gần hơn với hướng dẫn kiểu PEP8. Lưu ý khoảng trắng sau dấu phẩy trong danh sách tham số, dấu cách xung quanh toán tử gán = (nhưng không phải khi = được sử dụng cho tham số từ khóa chức năng) và nói not axes thay vì axes == None.

+1

Xin cảm ơn Ghopper21 cho câu trả lời của bạn. Đây là những gì tôi muốn xem. Có, cho dù đó là nhiều pythonic nên đưa vào tài khoản hình ảnh lớn hơn. Cũng cảm ơn cho việc định dạng lại mã, và định dạng lại một cái nhìn tốt hơn :) – wiswit

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