簡體   English   中英

如何檢查函數的參數?

[英]How to check arguments of the function?

我以這種方式定義了函數:

def f1 (a, b, c = None, d = None):
    .....

如何檢查ab不等於某個值。 例如,我要檢查它們是否不是空字符串,例如""" "

考慮類似的東西。

arguments = locals()
for item in arguments:
    check_attribute(item, arguments[item])

然后檢查參數是否不是""" " 但是在這種情況下,它還將嘗試檢查None值(我不想做什么)。

一種典型的方法是:

import sys

...

def check_attribute(name, value):
    """Gives warnings on stderr if the value is an empty or whitespace string.

       All other values, including None, are OK and give no warning.
    """
    if isinstance(value, basestring) and (not value or value.isspace()):
        print>>sys.stderr, "Invalid value %r for argument %r" % (value, name)

當然,根據應用程序的語義,如果問題非常嚴重,也可以發出警告或引發異常。

一個人可能應該將所有檢查委托給一個函數,而不是循環執行要檢查其args的函數(后者將在應用程序邏輯中間粘貼“檢查代碼”的痕跡-最好將其保留或方式...):

def check_arguments(d):
    for name, value in d.iteritems():
        check_attribute(name, value)

函數將是:

def f1 (a, b, c=None, d=None):
    check_arguments(locals())
    ...

您也可以編寫一個裝飾器以便能夠編碼

@checked_arguments
def f1 (a, b, c=None, d=None):
   ...

(使檢查代碼 “雜亂無章”),但是除非您確實有很多功能需要這種檢查,否則這可能被認為是過大的!

在裝飾器中,參數名自省(雖然可行,這要歸功於模塊inspect )比在函數本身內部要簡單得多,這就是為什么我最喜歡的設計方法是在這種情況下避免使用裝飾器方法(簡單性非常好;- )。

編輯 -由於OP明確要求裝飾器,因此顯示了如何實現裝飾器(盡管未闡明原因)。

主要問題(在python 2.6和更早版本中)是包裝器構造的映射等效於Python為您創建的locals() ,但需要在通用包裝器中顯式完成。

但是 -如果您使用新的2.7, 那么inspect.getcallargs您做到! 因此,問題變得更加簡單,裝飾器可能在更多情況下也值得做(如果您使用的是2.6或更早的版本,我仍然建議避免使用裝飾器方法,對於這種專門用途,這種方法會更加復雜)。

因此,這是您在Python 2.7中所需要的(重用我上面定義的check_arguments函數):

import functools
import inspect

def checked_arguments(f):
  @functools.wraps(f)
  def wrapper(*a, **k):
    d = inspect.getcallargs(f, *a, **k)
    check_arguments(d)
    return f(*a, **k)
  return wrapper

2.7之前版本中的困難完全來自於實現相當於inspect.getcallargs的困難-因此,我希望,如果您確實需要這種裝飾器,則可以直接從www.python.org下載Python 2.7和將其安裝在您的盒子上!-)(如果這樣做,您還會得到更多的好東西,並且比任何以前的Python版本都可獲得更多的支持周期,因為2.7被定為Python的最新版本。 2.*行)。

為什么不能通過名稱來引用值?

def f1 (a, b, c=None, d=None):
    if not a.strip():
        print('a is not empty')

如果您有很多參數,則值得將函數簽名更改為:

def f2 (*args, c=None, d=None):
    for var in args:
        if not var.strip():
            raise ValueError('all elements should be non-empty')
for key, value in locals().items():
    if value is not None:
        check_attribute(key, value)

盡管正如其他人已經說過的那樣,您可以直接按名稱檢查參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM