कुछ वैध विकल्प/कार्य-राउंड हैं जिनका आप उपयोग कर सकते हैं।
1. शायद सबसे सरल व्यवस्था करने के लिए अजगर समारोह n_bins
फोन के लिए, और फिर (के एक थोड़ा संशोधित संस्करण) से परिणाम का उपयोग कॉल करने के लिए की गैर allocatable उत्पादन सरणियों के साथ create_hist
समारोह होगा सही आकार
अजगर में
अर्थात:
n_b = n_bins(a,dr) # don't need to pass n - inferred from a
bins,hist = create_hist(a,dr,n_b) # bins and hist are auto-allocated
create_hist
को फोरट्रान इंटरफेस के साथ
अब के रूप में
subroutine create_hist(a, n, dr, n_b, bins, hist)
integer, intent(in) :: n
real(8), intent(in) :: a(n)
real(8), intent(in) :: dr
integer, intent(in) :: n_b
integer, intent(out) :: hist(n_b)
real(8), intent(out) :: bins(n_b+1)
! code follows
! you also need to specify the function n_bins...
यह केवल मामलों में जहां आप n_bins
सस्ते में और बाहर create_hist
से कॉल कर सकते हैं में काम करता है परिभाषित किया। मुझे उन मामलों के लिए आवंटित सरणी अनुकरण करने के लिए 2 विधियों के बारे में पता है, जहां यह लागू नहीं होता है (यानी सरणी आकारों को काम करने के लिए कोड महंगा है और आसानी से अलग नहीं किया जा सकता है)।
2. पहला मॉड्यूल स्तर आवंटनीय सरणी (दस्तावेज here में वर्णित) का उपयोग करना है। यह अनिवार्य रूप से एक आवंटित वैश्विक चर है - आप अपने फ़ंक्शन को कॉल करते हैं, यह डेटा को वैश्विक चर में सहेजता है और फिर आप इसे पायथन से एक्सेस करते हैं। नुकसान यह है कि यह थ्रेड-सुरक्षित नहीं है (यानी।यह बुरा है अगर आप समानांतर में एक साथ create_hist
फोन)
module something
real(8), allocatable :: bins(:)
integer, allocatable :: hist(:)
contains
subroutine create_hist(a,n,dr)
integer, intent(in) :: n
real(8), intent(in) :: a(n)
real(8), intent(in) :: dr
integer :: n_b
n_b = n_bins(a,n,dr)
allocate(bins(n_b+1))
allocate(hist(n_b))
! code follows
end subroutine
end module
अजगर कॉल तो लग रहा है
something.create_hist(a,n,dr)
bins = something.bins # or possible bins = copy.copy(something.bins)
hist = something.hist # or possible hist = copy.copy(something.hist)
3. अन्य तरीके से जो मैं काफी पसंद ही समारोह के भीतर सरणियों आवंटित करने के लिए है की तरह (यानी पैरामीटर के रूप में उन्हें बाहर/बाहर पास न करें)। हालांकि, आप जो करते हैं वह एक पायथन कॉलबैक फ़ंक्शन है जिसे अंत में बुलाया जाता है और सरणी बचाता है। यह थ्रेड-सुरक्षित है (मुझे विश्वास है)।
fortran कोड तो जैसे
subroutine create_hist(a,n,dr,callback)
integer, intent(in) :: n
real(8), intent(in) :: a(n)
real(8), intent(in) :: dr
external callable ! note: better to specify the type with an interface block (see http://www.fortran90.org/src/best-practices.html#callbacks)
integer :: n_b
real(8), allocatable :: bins(:)
integer, allocatable :: hist(:)
n_b = n_bins(a,n,dr)
allocate(bins(n_b+1))
allocate(hist(n_b))
! code follows
call callable(bins,hist,n_b)
end subroutine
दिखता दुर्भाग्य से यह तो थोड़ा और अधिक शामिल है।
python module create_hist__user__routines
interface create_hist_user_interface
subroutine callable(bins,hist,n_b) ! in :f:my_fortran_file.f90:stuff:create_hist:unknown_interface
real(kind=8), dimension(n_b+1) :: bins
integer, dimension(n_b) :: hist
integer :: n_b
end subroutine callable
end interface create_hist_user_interface
end python module create_hist__user__routines
: - (के रूप में उपयुक्त नाम बदलने के इस
fortran_module
नामक एक पायथन मॉड्यूल का निर्माण करना है), और फिर कॉलबैक फ़ंक्शन के आयामों को स्पष्ट करने का यह प्रासंगिक लाइनों को संशोधित आप कमांड
f2py -m fortran_module -h fortran_module.pyf my_fortran_file.f90
साथ एक हस्ताक्षर फ़ाइल बनाने की आवश्यकता
संकलन कि f2py -c fortran_module.pyf my_fortran_file.f90
हुआ और उसके अजगर आवरण के साथ (यदि आप एक आसान इंटरफ़ेस देने के लिए) है कि लग रहा है
तरह
def create_hist(a,dr):
class SaveArraysCallable(object):
def __call__(self,bins,hist):
self.bins = bins.copy()
self.hist = hist.copy()
f = SaveArrayCallable()
fortran_module.create_hist(a,dr,f)
return f.bins, f.hist
सारांश
कई मामलों के लिए विकल्प 1 शायद सबसे अच्छा है। अन्यथा विकल्प 2 या विकल्प 3. मैं विकल्प 3 पसंद करता हूं क्योंकि इससे बचने के लिए मल्टीथ्रेडिंग समस्याएं नहीं हैं (लेकिन वास्तव में यह एक कोने-केस है जिसे आप कभी नहीं देख पाएंगे)। विकल्प 2 को कार्यान्वित करना आसान है।
क्या पर्याप्त पर्याप्त आकार-आकार तर्क कार्य भी होगा? और वहां "लौटा आकार" तर्क भी होना चाहिए ताकि कॉलर जानता है कि सरणी कितनी मान्य है (उपयोग के मामले पर निर्भर करता है, मुझे यकीन है)? [किसी चीज से ज्यादा चीजों की अज्ञानता में पूछना।] – francescalus
हां, मान लिया गया आकार भी काम करेगा। आप लौटे आकार के बारे में भी सही हैं। अन्यथा यह (वे एक नकारात्मक संख्या, या कुछ और करने के लिए प्रारंभ किया जा सकता है 'bins' के मूल्यों से अनुमान लगाया जा करने के लिए? आप इसे परीक्षण किया होगा। –