ฉันควรตั้งชื่อฟังก์ชั่นที่คืนค่าใน Python อย่างไร?


13

ฉันสับสนเกี่ยวกับการเลือกชื่อสำหรับการทำงานของฉันในหลาม บางครั้งหลามในตัวฟังก์ชั่นที่มีความจำเป็นเช่นฟังก์ชั่นและวิธีสตริงprint findบางครั้งพวกเขาไม่ได้เช่นlenชื่อของมันไม่ได้เป็นความจำเป็นเช่นcalculate_lenตัวอย่างและไม่ได้เป็นtypefind_type

ฉันสามารถเข้าใจว่าprintคืนค่าที่เราไม่ได้ใช้ (เช่นNone) และทำบางสิ่ง (เช่นมันจะแสดงสตริงบนหน้าจอ) ดังนั้นชื่อของมันจึงมีความจำเป็น

แต่lenกลับเป็นค่าที่เราใช้และทำอะไรบางอย่าง (เช่นการคำนวณจำนวนรายการที่มีอยู่ในลำดับหรือการแมป.) และชื่อของมันไม่ได้เป็นความจำเป็น บนมืออื่น ๆ , findวิธีสตริง (เป็นlen) ส่งกลับค่าที่เราใช้และไม่บางสิ่งบางอย่างและชื่อของมันคือความจำเป็น

สิ่งที่ทำให้คำถามนี้คือฉันใส่สคริปต์ที่เข้ารหัสและถอดรหัสสตริงโดยใช้ Caesar cipher เพื่อตรวจสอบ ผู้วิจารณ์กล่าวว่า:

เป็นเพียงความรู้สึก: ฟังก์ชั่นทำสิ่งต่างๆ ดังนั้นชื่อที่ดีสำหรับการทำงานเป็นความจำเป็น: ฉันต้องการใช้แทนrotate_letterrotated_letter

rotated_letterส่งคืนสตริงตัวอักษรเดี่ยวที่แทนตัวอักษรที่หมุนด้วยตัวเลข ผมไม่ทราบว่าสิ่งที่ดีกว่าที่ผมใช้rotated_letterเป็นมันจะกลับค่าเช่นrandintฟังก์ชั่นในโมดูลสุ่มgenerate_randintก็เป็นได้

ดังนั้นในกรณีนี้ฉันจะตั้งชื่อฟังก์ชันที่ส่งกลับค่าที่จะใช้อย่างไร ฉันควรจะให้ชื่อมีความจำเป็นหรือเพียงแค่เป็นรูปธรรม ในกรณีอื่น ๆ จะเห็นได้ชัดว่าจะทำอย่างไรเช่นฟังก์ชั่นบูลีนเช่นis_evenและis_palindromeเราก็ทำให้มันเหมือนคำถามใช่ / ไม่ใช่และฟังก์ชั่นที่เพิ่งทำและคืนค่าที่ไม่ได้ใช้ (เช่นNone), printและวิธีรายการsort.


ที่จริงแล้วเป็นวิธีปฏิบัติทั่วไป (ฉันจะพูดแบบแผน) เพื่อใช้สิ่งจำเป็นเมื่อตั้งชื่อฟังก์ชั่น ตัวอย่างเช่นคุณตั้งชื่อตัวแปรที่จัดเก็บตัวอักษรหมุนของฟังก์ชัน rotated_letter ได้อย่างไร
JoulinRouge

นั่นไม่ใช่วิธีคิดตัวอย่างที่ดีของคุณ lenตัวอย่างเช่นคิดว่าดีกว่า "ความยาว" - คุณจะได้คำอธิบายระดับเมตาของการโต้แย้ง
Izkata

คำตอบ:


10

ใช้คำกริยาที่เหมาะสมถ้าเป็นคำนามที่สั้นและไม่คลุมเครือ

เวลาส่วนใหญ่ฟังก์ชั่นควรเป็นคำกริยาและคลาส (จำเป็น) ตัวแปรและพารามิเตอร์ควรเป็นคำนาม @propertyแอตทริบิวต์นี้ยังควรเป็นคำนามรวมทั้งผู้ที่สร้างขึ้นโดยใช้ โดยเฉพาะอย่างยิ่งในกรณีของฟังก์ชั่นที่มีผลข้างเคียง [1] หากฟังก์ชันส่งคืนบางสิ่งคุณควรประเมินว่าคำกริยาเพิ่มบางสิ่งหรือเป็นเพียง "เสียงรบกวน":

  • make_list(foo)vs. list(foo): คำนามอ่านง่ายกว่ากริยา นอกจากนี้ยังlistเป็นชั้นเรียนและชั้นเรียนควรเป็นคำนาม
  • open(foo)vs. file(foo): คำกริยาง่ายต่อการอ่านมากกว่าคำนามและมันมีเหตุผลมากกว่าที่จะให้ "ตัวเลือก" กับคำกริยามากกว่าคำนามดังนั้นคำนามจึงถูกลบใน Python 3 open()ยังคงเป็น "มาตรฐาน" [2] เพื่อสร้างวัตถุไฟล์ใน Python 3
  • foo.get_bar()vs. foo.bar()vs. foo.bar(สมมติfooและbarเป็นคำนามทั้งคู่): ตัวเลือกแรกนั้นถูกต้องเพราะ "รับ" ไม่ได้เพิ่มอะไรที่เรายังไม่รู้อยู่ อย่างที่สองก็เหมาะสมถ้าการbarออกจาก a fooเป็นการดำเนินการที่อาจมีราคาแพงและ / หรือมีผลข้างเคียง (คุณอาจพิจารณาBar(foo)ว่าBarเป็นคลาส) ที่สามคือความเหมาะสมว่านี้คือการดำเนินการถูกกับไม่มีผลข้างเคียงและการใช้งานทางเลือกที่ไม่น่าจะทำให้มันมีราคาแพง
  • xs.sort()vs. sorted(xs)if xsis list: อันแรกมีความจำเป็น: เรียงลำดับรายการ มันปรับเปลี่ยนรายการในสถานที่และส่งกลับไม่มีอะไร ที่สองคือการประกาศ: รายการที่เรียงลำดับซึ่งเป็นสิ่งที่มันกลับมา ทั้งคู่เป็นคำกริยา

[1]: โดยปกติแล้วการคืนค่าและการมีผลข้างเคียงจะไม่เกิดร่วมกันเว้นแต่คุณจะมีเหตุผลในการออกแบบที่น่าสนใจเพื่อรวมเข้าด้วยกัน ดังนั้นฟังก์ชั่นที่มีผลข้างเคียงไม่น่าจะคืนสิ่งใดไปดังนั้นการทำให้คำนามเป็นสิ่งที่สมเหตุสมผล
[2]: มีการดำเนินการระดับต่ำกว่าระดับปานกลางในioโมดูลซึ่งสามารถใช้เพื่อเพิ่มหรือลบการบัฟเฟอร์ไฟล์การเข้ารหัสข้อความอัตโนมัติ ฯลฯ และสิ่งเหล่านี้ส่วนใหญ่เป็นคำนามเนื่องจากเป็นคลาสเชิงวัตถุ ผู้ใช้ส่วนใหญ่ไม่จำเป็นต้องเล่นกับสิ่งเหล่านี้โดยตรง open()เลือกคลาสที่เหมาะสมแทนและสร้างอินสแตนซ์ให้โดยอัตโนมัติ


ขอบคุณ! ใน" foo.get_bar() vs.` foo.bar ()` vs. foo.bar"ความแตกต่างระหว่างตัวที่สองกับตัวที่สามคืออะไร?
Mahmood Muhammad Nageeb

ที่สามเป็นคุณสมบัติหรือแอตทริบิวต์เปล่า ประการที่สองคือวิธีการ
Kevin

ดังนั้นถ้าฉันเข้าใจมันเหมาะสมแล้วที่จะไม่ทำrotated_letterสิ่งที่จำเป็นและทำให้มันเป็นความจริงใช่มั้ย
Mahmood Muhammad Nageeb

ในกรณีนี้ฉันไม่แน่ใจว่าletterมีความหมายตามบริบทหรือไม่
เควิน

+1 สำหรับการกล่าวถึงlistเป็นคลาส
DušanMaďar

0

rotated_letterดูไม่เหมือนวิธี ดูเหมือนว่าทรัพย์สิน ซึ่งหมายความว่าความคิดแรกคือการทำ:

var letter = caesar.rotated_letter

คาดหวังว่าletterจะมีค่าของสตริงประเภทไม่ใช่ฟังก์ชั่น จากที่นั่นคุณเลือกชื่ออื่นเช่น:

def rotate_letter(self):
    pass

หรือคุณใช้คุณสมบัติแทน:

@property
def rotated_letter(self):
    return self.whatever

lenและtypeถูกตั้งชื่อเช่นนั้นเพราะชื่ออื่น ๆ นั้นจะต้องมีความยาวในการพิมพ์ พวกเขาถูกใช้บ่อยและมีสถานะพิเศษของฟังก์ชั่น Python หลักที่โปรแกรมเมอร์ Python ทุกคนจะเรียนรู้ต่อไปทำให้ชื่อของพวกเขาไม่เกี่ยวข้องมากไปกว่าชื่อของห้องสมุดบุคคลที่สาม

lenโดยเฉพาะอย่างยิ่งเป็นตัวอย่างที่ดีของสิ่งที่คุณไม่ควรทำในของคุณรหัส: คุณคาดว่าจะใช้ชื่อเต็มเช่นlength(เว้นแต่แบบสั้นเป็นที่นิยมมากเช่นmax) compute_lengthและใช้คำกริยาเช่น หรือมันอาจจะเป็นสถานที่ให้บริการ: กลายเป็นlen([1, 5, 6]) [1, 5, 6].lengthยกตัวอย่างเช่นใน C #, new [] { ... }.Lengthรูปแบบที่ต่อมาถูกนำมาใช้:

โปรดทราบว่าอาจมีเหตุผลทางประวัติศาสตร์เช่นlen: ภาษาอื่น ๆ เช่น C # Countซึ่งเป็นที่ต้องการซึ่งมักจะเป็นวิธีการ (แม้ว่าพฤติกรรมจะไม่สอดคล้องกันอย่างน่าเสียดายผ่าน. NET Framework) Countเป็นคำกริยาดังนั้นโดยสัญชาตญาณคุณมีแนวโน้มที่จะเรียกมันว่าเป็นวิธีการ

ส่งคืนค่าหรือดำเนินการแอ็คชัน

ฟังก์ชั่นที่คาดว่าจะทำการกระทำ ถ้ามันเพิ่งจะส่งกลับค่ามันควรจะเป็นทรัพย์สิน คุณมีคำใบ้ว่าควรเปลี่ยนฟังก์ชั่นเป็นคุณสมบัติเมื่อ:

  • ฟังก์ชั่นแทบจะไม่มีreturn ...คำสั่ง

  • ชื่อฟังก์ชั่นของที่มาจากธรรมชาติในใจของคุณเป็นเช่นเดียวกับในget_somethingproduct.get_price()

ตอนนี้ถ้าคุณมีฟังก์ชั่นมันอาจเป็นหนึ่งในสี่ประเภท:

  • มันสามารถบริสุทธิ์นั่นคือคืนค่าโดยไม่ส่งผลกระทบต่อสิ่งแวดล้อม ตัวอย่าง: road.measure_distance().

  • มันสามารถส่งผลกระทบต่อสิ่งแวดล้อมโดยไม่ต้องคืนสิ่งใด ตัวอย่าง: product_database.remove_record(1234).

  • มันสามารถส่งผลกระทบต่อสภาพแวดล้อมและคืนค่า ตัวอย่าง: ใช้เช่นvalue.increment()value++

  • มันไม่สามารถทำอะไรและไม่คืนอะไรเลย ตัวอย่าง: time.sleep(1).

มีบางกรณีที่ชื่ออาจให้คำแนะนำที่ชัดเจนเกี่ยวกับประเภทของฟังก์ชั่น แต่ในหลายกรณีคุณจะไม่สามารถรู้ประเภทจากชื่อของมันได้


ฉันคิดว่าคำตอบคือ "ใช่" แต่ฉันต้องถามว่า: คุณตอบโดยสิ้นเชิงจากมุมมองของ Python หรือไม่? เพราะในภาษาอื่นการแยกคุณสมบัติเทียบกับคุณสมบัติของคุณนั้นไม่ได้เป็นจริงเสมอไป ยังไม่เป็นความจริงที่ฟังก์ชั่น "ต้องดำเนินการ" นี่คือการประชุมใน Python หรือไม่? (ฉันเขียน Python แต่ยังไม่ได้อ่าน PEP ทั้งหมดและฉันไม่ใช่ผู้เชี่ยวชาญแน่นอนฉันไม่ได้ลงคะแนน BTW)
Andres F.

@AndresF: ฉันกำลังตอบจากมุมมองของ Python ในภาษาเช่น Java ที่ไม่มีคุณสมบัติgetSomethingและsetSomethingเป็นชื่อปกติที่ใช้แทนคุณสมบัติ
Arseni Mourzenko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.