Tôi có một tên hàm được lưu trữ trong một biến như thế này:
myvar = 'mypackage.mymodule.myfunction'
và bây giờ tôi muốn gọi chức năng của mình như thế này
myvar(parameter1, parameter2)
Cách dễ nhất để đạt được điều này là gì?
Tôi có một tên hàm được lưu trữ trong một biến như thế này:
myvar = 'mypackage.mymodule.myfunction'
và bây giờ tôi muốn gọi chức năng của mình như thế này
myvar(parameter1, parameter2)
Cách dễ nhất để đạt được điều này là gì?
Câu trả lời:
funcdict = {
'mypackage.mymodule.myfunction': mypackage.mymodule.myfunction,
....
}
funcdict[myvar](parameter1, parameter2)
Sẽ đẹp hơn nhiều khi có thể chỉ lưu trữ chính hàm, vì chúng là các đối tượng hạng nhất trong python.
import mypackage
myfunc = mypackage.mymodule.myfunction
myfunc(parameter1, parameter2)
Tuy nhiên, nếu bạn phải nhập động gói, thì bạn có thể đạt được điều này thông qua:
mypackage = __import__('mypackage')
mymodule = getattr(mypackage, 'mymodule')
myfunction = getattr(mymodule, 'myfunction')
myfunction(parameter1, parameter2)
Tuy nhiên, hãy nhớ rằng tất cả công việc đó áp dụng cho bất kỳ phạm vi nào bạn hiện đang ở. Nếu bạn không duy trì chúng bằng cách nào đó, bạn không thể tin tưởng vào việc chúng ở lại nếu bạn rời khỏi phạm vi cục bộ.
def f(a,b):
return a+b
xx = 'f'
print eval('%s(%s,%s)'%(xx,2,3))
ĐẦU RA
5
Dễ nhất
eval(myvar)(parameter1, parameter2)
Bạn không có hàm "con trỏ". Bạn có một chức năng "tên".
Mặc dù điều này hoạt động tốt, bạn sẽ có một số lượng lớn người nói với bạn rằng đó là "không an toàn" hoặc "rủi ro bảo mật".
modname, funcname = myvar.rsplit('.', 1)
getattr(sys.modules[modname], funcname)(parameter1, parameter2)
eval(compile(myvar,'<str>','eval'))(myargs)
compile (..., 'eval') chỉ cho phép một câu lệnh duy nhất, do đó không thể có các lệnh tùy ý sau một cuộc gọi, nếu không sẽ có Lỗi cú pháp. Sau đó, một chút xác thực nhỏ ít nhất có thể hạn chế biểu thức thành một thứ gì đó trong khả năng của bạn, chẳng hạn như kiểm tra 'mypackage' để bắt đầu.
Tôi đã gặp sự cố tương tự khi tạo thư viện để xử lý xác thực. Tôi muốn chủ sở hữu ứng dụng sử dụng thư viện của mình có thể đăng ký một lệnh gọi lại với thư viện để kiểm tra ủy quyền đối với các nhóm LDAP mà người được xác thực đang ở trong đó. Cấu hình sẽ được chuyển vào dưới dạng tệp config.py được nhập và chứa một lệnh với tất cả các thông số cấu hình.
Tôi phải làm việc này:
>>> class MyClass(object):
... def target_func(self):
... print "made it!"
...
... def __init__(self,config):
... self.config = config
... self.config['funcname'] = getattr(self,self.config['funcname'])
... self.config['funcname']()
...
>>> instance = MyClass({'funcname':'target_func'})
made it!
Có cách nào để làm điều này không?
myvar = mypackage.mymodule.myfunction
sạch hơn nhiều.