पायथन में एक फ़ंक्शन के दो तर्कों को कैसे स्थानांतरित करना है?


11

पायथन फ़ंक्शन के कॉल में मैं दो तर्कों को कैसे स्वैप कर सकता हूं?

अगर मैं pointइन दो तर्कों के बीच की जगह पर रखूँ:

self.assertEqual(json.loads(some.data), json_data)

और फिर M-t( transpose-words), मुझे मिलता है:

self.assertEqual(json.loads(some.json), data_data)

दूसरी ओर CMt ( transpose-sexps) के साथ :

self.assertEqual(json.loadsjson_data, (some.data))

मुझे क्या चाहिए:

self.assertEqual(json_data, json.loads(some.data))

क्या कोई आज्ञा है जो ऐसा करेगी?


2
मैंने कोशिश नहीं की है, लेकिन इसके लिए एंकरेड ट्रांसपोज़ का इस्तेमाल किया जा सकता है; हालाँकि, यह 2-चरणीय प्रक्रिया है।
कौशल मोदी

एक कोर फंक्शन होता है जिसे फंक्शन transpose-subrलेता है forwardऔर इसे transposeफंक्शन में ट्रांसलेट करता है। इसलिए अगर हमारे पास c-forward-arglist(एक फंक्शन से आगे बढ़ने के लिए फंक्शन होता है तो - AFAICT यह मौजूद नहीं है) हमारे पास होगा c-transpose-arglist
ब्रेंडन

जवाबों:


4

यह कुछ ऐसा है जो मैं भी लंबे समय से करना चाहता था, और यहां मैंने इस पर काम करने के लिए कुछ प्रेरणा पाई है। यह शायद बहुत मजबूत नहीं है, लेकिन पहली कोशिश में ऐसा लगता है कि मैंने उन मामलों को कवर किया है:

(defun my/calculate-stops ()
  (save-excursion
    (let ((start
           (condition-case e
               (while t (backward-sexp))
             (error (point))))
          stops)
      (push start stops)
      (condition-case e
          (while t
            (forward-sexp)
            (when (looking-at "\\s-*,")
              (push (point) stops)))
        (error (push (point) stops)))
      (nreverse stops))))

(defun my/transpose-args ()
  (interactive)
  (when (looking-at "\\s-") (backward-sexp))
  (cl-loop with p = (point)
           with previous = nil
           for stop on (my/calculate-stops)
           for i upfrom 0
           when (<= p (car stop)) do
           (when previous
             (let* ((end (cadr stop))
                    (whole (buffer-substring previous end))
                    middle last)
               (delete-region previous end)
               (goto-char previous)
               (setf middle (if (> i 1) (- (car stop) previous)
                              (string-match "[^, \\t]" whole 
                                            (- (car stop) previous)))
                     last (if (> i 1) (substring whole 0 middle)
                            (concat (substring whole (- (car stop) previous) middle)
                                    (substring whole 0 (- (car stop) previous)))))
               (insert (substring whole middle) last)))
           (cl-return)
           end do (setf previous (car stop))))

मुझे यह तब मिलता है जब बिंदु अंतरिक्ष पर होता है (कॉमा पर काम करता है): चलो *: गलत प्रकार का तर्क: पूर्णांक-या-मार्कर-पी, नील
क्रोड लैंगशान

@ क्रोडलंगशन फिक्स अपेक्षाकृत आसान था (ऊपर देखें)। मज़ेदार बात मैंने एक विकल्प लिखकर स्टीफ़न की सलाह का पालन करने की कोशिश की forward-sexp-function, और यह अल्पविराम के कारण बहुत ही बोझिल प्रतीत हुआ। फिर मैंने traspose-sexpएक ही काम करने के लिए नकल करने की कोशिश की , और, फिर से, कॉमा के लिए खाता होने से यह वास्तव में मुश्किल हो जाता है। मैं दावा नहीं करता कि यह हमेशा सही काम करता है जब यह सीमांकक की सूची में आता है, हो सकता है कि केवल आधा समय ...
wvxvw

यह (aa, bb)तब विफल हो जाता है जब कर्सर पहले पर होता है a। यह भी सुर लिए काम नहीं करता सुर ऊपर किसी भी तरह भोजनालयों। FOO(aaa *, bbb, ccc)*
आइडियामैन 42

इसके अलावा FOO(&aaa, bbb)(और स्वैप नहीं करता है) के लिए विफल रहता है ।
ideasman42 2

4

मैं transpose-sexpsउस भिन्नता का उपयोग करता हूं जो आपके द्वारा बताए गए मामले के लिए दिखती है और चीजों को अलग-अलग-अल्पविरामों में स्थानांतरित करती है, या बस नियमित रूप से करती है transpose-sexps। यह कर्सर को आगे खींचने के स्थान पर छोड़ देता है, जो थोड़ा अलग है लेकिन मुझे व्यक्तिगत रूप से पसंद है।

(defun my-transpose-sexps ()
  "If point is after certain chars transpose chunks around that.
Otherwise transpose sexps."
  (interactive "*")
  (if (not (looking-back "[,]\\s-*" (point-at-bol)))
      (progn (transpose-sexps 1) (forward-sexp -1))
    (let ((beg (point)) end rhs lhs)
      (while (and (not (eobp))
                  (not (looking-at "\\s-*\\([,]\\|\\s)\\)")))
        (forward-sexp 1))
      (setq rhs (buffer-substring beg (point)))
      (delete-region beg (point))
      (re-search-backward "[,]\\s-*" nil t)
      (setq beg (point))
      (while (and (not (bobp))
                  (not (looking-back "\\([,]\\|\\s(\\)\\s-*" (point-at-bol))))
        (forward-sexp -1))
      (setq lhs (buffer-substring beg (point)))
      (delete-region beg (point))
      (insert rhs)
      (re-search-forward "[,]\\s-*" nil t)
      (save-excursion
        (insert lhs)))))

मेरे लिए यह मुखर कॉल (अंतरिक्ष पर बिंदु के साथ शुरू) की शुरुआत में व्हाट्सएप छोड़ता है।
क्रोड लैंगशान

1
यह कीवर्ड तर्कों के लिए काम नहीं करता है जैसे: f(a=1, b=2)(यह चारों ओर स्थानांतरित होता है)
एट रिघ

1
जबकि प्रश्न सी कोड से अधिक है, यह उत्तर काम करता है f(a=1, b=2)- emacs.stackexchange.com/a/47930/2418
ideasman42

2

SMIE का उपयोग करने वाले मोड में, transpose-sexpउस स्थिति के लिए सही तरीके से काम करना चाहिए। वे तब भी विफल रहेंगे जब infix प्रतीक (उर्फ "विभाजक") एक ,(या ;) नहीं है, लेकिन एक शब्द (जैसे and) है।

इसलिए, मेरी राय यह है कि इसके लिए कमांड है transpose-sexpऔर जब यह सही ढंग से काम नहीं करता है, तो मैं इसे बग के रूप में मानता हूं (लेकिन एक बग जो कठिन हो सकता है और / या ठीक करने के लिए समय लेता है और कम प्राथमिकता रखता है, इसलिए डॉन ' टी अपनी सांस पकड़)। इसे ठीक करने का तरीका forward-sexp-functionएक फ़ंक्शन पर सेट करके है जिसे पता चल जाएगा कि "मैं कॉमा देखने के बाद, मैं बस पूरे तर्क के आसपास कूदता हूं"।


1
मुझे लगता है कि जावा-मोड (उदाहरण के लिए) SMIE का उपयोग नहीं करता है? इसे ठीक करने के बारे में कोई कैसे जानेगा?
शमूएल एडविन वार्ड

1
नहीं, वास्तव में, सी जैसी भाषाओं के लिए प्रमुख मोड SMIE का उपयोग नहीं करते हैं और न केवल ऐतिहासिक कारणों के लिए: SMIE का पार्सर बस उन भाषाओं के लिए बहुत कमजोर है। यह कहा गया, SMIE का पार्सर ठीक काम करेगा यदि आप अल्पविराम द्वारा अलग किए गए दो तर्कों को स्वैप करना चाहते हैं (व्याकरण का यह भाग काफी सरल है), तो मुझे लगता है कि SMIE को कॉन्फ़िगर करना और इसका उपयोग करना संभव है, forward-sexp-functionलेकिन आपके पास होगा कुछ कोड जोड़ने के लिए केवल forward-sexp-function उन मामलों में SMIE का उपयोग करें जहां यह काफी अच्छी तरह से काम करता है, क्योंकि कई अन्य मामलों में यह भ्रमित करने वाले व्यवहार के परिणामस्वरूप होगा।
स्टीफन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.