ฟังก์ชั่นหนึ่งบรรทัดที่เรียกว่าครั้งเดียวเท่านั้น


120

พิจารณาฟังก์ชั่นแบบไม่มีพารามิเตอร์ ( แก้ไข:ไม่จำเป็น) ที่ดำเนินการรหัสบรรทัดเดียวและถูกเรียกเพียงครั้งเดียวในโปรแกรม (แม้ว่าจะเป็นไปไม่ได้ที่จะต้องใช้อีกครั้งในอนาคต)

มันสามารถทำการสืบค้นตรวจสอบค่าบางอย่างทำบางสิ่งที่เกี่ยวข้องกับ regex ... อะไรที่คลุมเครือหรือ "แฮ็ค"

เหตุผลเบื้องหลังสิ่งนี้คือการหลีกเลี่ยงการประเมินที่อ่านยาก:

if (getCondition()) {
    // do stuff
}

ซึ่งgetCondition()เป็นฟังก์ชั่นหนึ่งบรรทัด

คำถามของฉันคือ: นี่เป็นการปฏิบัติที่ดีหรือไม่? ดูเหมือนจะไม่เป็นไรสำหรับฉัน แต่ฉันไม่รู้เกี่ยวกับระยะยาว ...


9
ยกเว้นว่าส่วนของโค้ดของคุณมาจากภาษา OOP ที่มีตัวรับโดยนัย (เช่นนี้) สิ่งนี้จะเป็นการปฏิบัติที่ไม่ถูกต้องเนื่องจาก getCondition () ส่วนใหญ่อาจอาศัยสภาพโลก ...
Ingo

2
เขาอาจหมายถึงการที่ getCondition () อาจมีข้อโต้แย้ง?
user606723

24
@Ingo - บางสิ่งมีสถานะเป็น Global เวลาปัจจุบันชื่อโฮสต์หมายเลขพอร์ต ฯลฯ เป็น "Globals" ที่ถูกต้องทั้งหมด ข้อผิดพลาดในการออกแบบคือการทำให้เกิด Global จากบางสิ่งที่ไม่ใช่โดยทั่วโลก
James Anderson

1
ทำไมคุณไม่เพียงแค่อยู่ในสายgetCondition? ถ้ามันมีขนาดเล็กและใช้ไม่บ่อยนักตามที่คุณบอกว่ามันทำให้ชื่อนั้นไม่สำเร็จอะไรเลย
davidk01

12
davidk01: การอ่านรหัสได้
wjl

คำตอบ:


240

ขึ้นอยู่กับว่าหนึ่งบรรทัด หากบรรทัดสามารถอ่านได้และรัดกุมด้วยตัวเองฟังก์ชันอาจไม่จำเป็น ตัวอย่างง่าย ๆ :

void printNewLine() {
  System.out.println();
}

OTOH ถ้าฟังก์ชั่นให้ชื่อที่ดีกับบรรทัดของรหัสที่มีเช่นการแสดงออกที่ซับซ้อนและยากที่จะอ่านมันเป็นธรรมที่สมบูรณ์แบบ (สำหรับฉัน) ตัวอย่างที่คาดไว้ (แบ่งออกเป็นหลายบรรทัดเพื่อให้สามารถอ่านได้ที่นี่):

boolean isTaxPayerEligibleForTaxRefund() {
  return taxPayer.isFemale() 
        && (taxPayer.getNumberOfChildren() > 2 
        || (taxPayer.getAge() > 50 && taxPayer.getEmployer().isNonProfit()));
}

99
+1 คำมหัศจรรย์ที่นี่คือ "รหัสเอกสารด้วยตนเอง"
Konamiman

8
ตัวอย่างที่ดีของสิ่งที่ลุงบ็อบเรียกว่า "การห่อหุ้มเงื่อนไข"
Anthony Pegram

12
@Aditya: ไม่มีอะไรบอกว่าtaxPayerเป็นโลกในสถานการณ์นี้ บางทีคลาสนี้อาจเป็นTaxReturnและtaxPayerเป็นแอตทริบิวต์
อดัมโรบินสัน

2
นอกจากนี้ยังช่วยให้คุณสามารถจัดทำเอกสารฟังก์ชั่นในลักษณะที่สามารถหยิบขึ้นมาได้เช่น javadoc และเปิดเผยต่อสาธารณะ

2
@dallin, รหัสสะอาดของ Bob Martin แสดงตัวอย่างรหัสครึ่งชีวิตจำนวนมาก หากคุณมีฟังก์ชั่นมากเกินไปในคลาสเดียวบางทีคลาสของคุณใหญ่เกินไป?
PéterTörök

67

ใช่สิ่งนี้สามารถใช้เพื่อตอบสนองการปฏิบัติที่ดีที่สุด ตัวอย่างเช่นจะเป็นการดีกว่าถ้ามีฟังก์ชั่นที่ตั้งชื่ออย่างชัดเจนว่าจะทำงานบางอย่างแม้ว่าจะมีความยาวเพียงหนึ่งบรรทัดเท่านั้นกว่าจะมีบรรทัดของโค้ดนั้นในฟังก์ชันที่มีขนาดใหญ่กว่าและต้องการความคิดเห็นแบบบรรทัดเดียว นอกจากนี้บรรทัดของรหัสข้างเคียงควรปฏิบัติงานในระดับที่เป็นนามธรรมเดียวกัน ตัวอย่างที่เป็นตัวอย่างจะเป็นอย่างไร

startIgnition();
petrolFlag |= 0x006A;
engageChoke();

ในกรณีนี้จะเป็นการดีกว่าที่จะย้ายเส้นกลางไปยังฟังก์ชั่นที่ตั้งชื่อได้ดี


15
นั่นคือ 0x006A ที่น่ารัก: DA เป็นที่รู้จักกันดีว่าเชื้อเพลิงคาร์บอไนซ์ที่มีสารเติมแต่ง a, b และ c
Coder

2
+1 ฉันทุกคนใช้รหัสการจัดทำเอกสารด้วยตนเอง :) โดยวิธีการฉันคิดว่าฉันเห็นด้วยกับการคงระดับนามธรรมผ่านบล็อก แต่ฉันไม่สามารถอธิบายได้ว่าทำไม คุณจะช่วยขยายความคิดนั้นได้ไหม?
vemv

3
หากคุณเพียงแค่บอกว่าpetrolFlag |= 0x006A;ไม่มีการตัดสินใจใด ๆ มันจะเป็นการดีกว่าถ้าคุณพูดpetrolFlag |= A_B_C; โดยไม่มีฟังก์ชั่นเพิ่มเติม น่าengageChoke()จะเรียกได้ก็ต่อเมื่อpetrolFlagตรงตามเกณฑ์ที่กำหนดและควรพูดอย่างชัดเจนว่า 'ฉันต้องการฟังก์ชั่นที่นี่' เพียงนิดเล็ก ๆ น้อย ๆ คำตอบนี้เป็นพื้นจุดที่มิฉะนั้น :)
ทิมโพสต์

9
+1 สำหรับการชี้ให้เห็นว่ารหัสในวิธีการควรอยู่ในระดับที่เป็นนามธรรม @vemv เป็นวิธีปฏิบัติที่ดีเพราะจะทำให้โค้ดเข้าใจง่ายขึ้นโดยหลีกเลี่ยงความต้องการที่ใจของคุณจะกระโดดขึ้นและลงระหว่างระดับต่าง ๆ ของสิ่งที่เป็นนามธรรมในขณะที่อ่านโค้ด การผูกระดับนามธรรมให้สลับไปที่การเรียก / ส่งคืนเมธอด (เช่นโครงสร้าง "การข้าม") เป็นวิธีที่ดีในการทำให้โค้ดคล่องแคล่วและสะอาดยิ่งขึ้น
PéterTörök

21
ไม่มันเป็นมูลค่าที่สมบูรณ์แบบ แต่ความจริงที่ว่าคุณสงสัยว่ามันแค่เน้นจุด: ถ้ารหัสได้กล่าวว่าmixLeadedGasoline()คุณจะไม่ต้อง!
Kilian Foth

37

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

bool someConditionSatisfied = [complex expression];

สิ่งนี้จะให้คำแนะนำแก่ผู้อ่านโค้ดและบันทึกจากการแนะนำฟังก์ชั่นใหม่


1
บูลเป็นประโยชน์อย่างยิ่งหากชื่อฟังก์ชันเงื่อนไขนั้นยากหรืออาจทำให้เข้าใจผิด (เช่นIsEngineReadyUnlessItIsOffOrBusyOrOutOfService)
dbkk

2
ฉันมีประสบการณ์คำแนะนำนี้เป็นความคิดที่ไม่ดี: บูลและสภาพเบี่ยงเบนความสนใจจากธุรกิจหลักของฟังก์ชั่น นอกจากนี้สไตล์ที่ต้องการตัวแปรท้องถิ่นทำให้การปรับโครงสร้างยากขึ้น
Wolf

1
@ Wolf OTOH ฉันชอบสิ่งนี้กับการเรียกใช้ฟังก์ชั่นเพื่อลด "ความลึกของรหัส" IMO การกระโดดเข้าไปในฟังก์ชันเป็นการสลับบริบทที่ใหญ่กว่าโค้ดคู่ที่ชัดเจนและตรงไปตรงมาโดยเฉพาะถ้ามันส่งคืนบูลีน
Kache

@Kache ฉันคิดว่ามันขึ้นอยู่กับว่าคุณใช้รหัสวัตถุหรือไม่ในกรณี OOP การใช้ฟังก์ชั่นสมาชิกทำให้การออกแบบมีความยืดหยุ่นมากขึ้น มันขึ้นอยู่กับบริบทจริง ๆ ...
Wolf

23

นอกจากคำตอบของปีเตอร์หากเงื่อนไขนั้นอาจจำเป็นต้องได้รับการปรับปรุงในบางจุดในอนาคตโดยให้สรุปวิธีที่คุณแนะนำคุณจะมีจุดแก้ไขเพียงจุดเดียว

ทำตามตัวอย่างของปีเตอร์ถ้าเป็นเช่นนี้

boolean isTaxPayerEligibleForTaxRefund() {
  return taxPayer.isFemale() 
        && (taxPayer.getNumberOfChildren() > 2 
        || (taxPayer.getAge() > 50 && taxPayer.getEmployer().isNonProfit()));
}

กลายเป็นสิ่งนี้

boolean isTaxPayerEligibleForTaxRefund() {
  return taxPayer.isMutant() 
        && (taxPayer.getNumberOfThumbs() > 2 
        || (taxPayer.getAge() > 123 && taxPayer.getEmployer().isXMan()));
}

คุณทำการแก้ไขเพียงครั้งเดียวและได้รับการปรับปรุงในระดับสากล การบำรุงรักษาอย่างชาญฉลาดนี่เป็นข้อดี

ประสิทธิภาพที่ชาญฉลาดคอมไพเลอร์ที่ปรับให้เหมาะสมที่สุดจะลบการเรียกใช้ฟังก์ชันและอินไลน์บล็อกโค้ดขนาดเล็กอย่างไรก็ตาม การเพิ่มประสิทธิภาพบางอย่างเช่นนี้อาจลดขนาดบล็อก (โดยการลบคำแนะนำที่จำเป็นสำหรับการเรียกใช้ฟังก์ชันส่งคืนและอื่น ๆ ) ดังนั้นจึงเป็นเรื่องปกติที่จะต้องทำแม้จะอยู่ในสภาพที่อาจป้องกันไม่ให้อินไลน์


2
ฉันรู้อยู่แล้วถึงประโยชน์ของการรักษาจุดแก้ไขจุดเดียวนั่นคือสาเหตุที่คำถามบอกว่า "... เรียกครั้งเดียว" อย่างไรก็ตามมันเป็นเรื่องดีที่ได้ทราบเกี่ยวกับการเพิ่มประสิทธิภาพของคอมไพเลอร์เหล่านั้นฉันคิดเสมอว่าพวกเขาทำตามคำแนะนำประเภทนี้อย่างแท้จริง
vemv

การแยกวิธีการทดสอบเงื่อนไขอย่างง่ายมีแนวโน้มที่จะบอกเป็นนัยว่าเงื่อนไขอาจมีการเปลี่ยนแปลงโดยการเปลี่ยนวิธีการ ความหมายดังกล่าวมีประโยชน์เมื่อมันเป็นจริง แต่อาจเป็นอันตรายได้หากไม่ใช่ ตัวอย่างเช่นสมมติว่ารหัสจำเป็นต้องแบ่งสิ่งต่าง ๆ เป็นวัตถุที่มีน้ำหนักเบาวัตถุสีเขียวหนักและวัตถุที่ไม่ใช่สีเขียวหนัก วัตถุมีคุณสมบัติ "seemGreen" อย่างรวดเร็วซึ่งเชื่อถือได้สำหรับวัตถุหนัก แต่อาจส่งคืนผลบวกปลอมด้วยวัตถุที่มีน้ำหนักเบา พวกเขายังมีฟังก์ชั่น "measureSpectralResponse" ซึ่งทำงานช้า แต่จะทำงานได้อย่างน่าเชื่อถือสำหรับวัตถุทั้งหมด
supercat

ความจริงที่ว่าseemsGreenจะไม่น่าเชื่อถือกับวัตถุที่มีน้ำหนักเบาจะไม่เกี่ยวข้องถ้ารหัสไม่เคยสนใจว่าวัตถุที่มีน้ำหนักเบาเป็นสีเขียว หากคำจำกัดความของ "lightweight" เปลี่ยนแปลงเช่นว่าวัตถุที่ไม่ใช่สีเขียวซึ่งส่งคืนค่าจริงseemsGreenไม่ได้ถูกรายงานว่าเป็น "lightweight" ดังนั้นการเปลี่ยนคำจำกัดความของ "lightweight" อาจทำลายรหัสที่ทดสอบวัตถุ เป็น "สีเขียว" ในบางกรณีการทดสอบความเป็นมิตรต่อสิ่งแวดล้อมและน้ำหนักร่วมกันในรหัสอาจทำให้ความสัมพันธ์ระหว่างการทดสอบชัดเจนขึ้นกว่าการทดสอบแบบแยกกัน
supercat

5

นอกเหนือจากความสามารถในการอ่าน (หรือเสริมประกอบ) มันช่วยให้การเขียนฟังก์ชั่นในระดับที่เหมาะสมของนามธรรม


1
ฉันเกรงว่าฉันไม่เข้าใจความหมายของคุณ ...
vemv

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

4

มันขึ้นอยู่กับ. บางครั้งมันจะดีกว่าที่จะแค็ปซูลแสดงออกในฟังก์ชั่น / วิธีแม้ว่ามันจะเป็นเพียงหนึ่งบรรทัด ถ้ามันซับซ้อนในการอ่านหรือคุณต้องการมันในหลาย ๆ ที่ฉันคิดว่ามันเป็นการฝึกฝนที่ดี ในระยะยาวการบำรุงรักษาง่ายขึ้นเนื่องจากคุณได้แนะนำจุดเปลี่ยนแปลงเดียวและอ่านง่ายขึ้น

อย่างไรก็ตามบางครั้งก็เป็นเพียงสิ่งที่คุณไม่ต้องการ เมื่อนิพจน์นั้นอ่านง่ายและ / หรือปรากฏในที่เดียวแล้วอย่าปิดมัน


3

ฉันคิดว่าถ้าคุณมีเพียงไม่กี่คนมันก็โอเค แต่ปัญหาเกิดขึ้นเมื่อมีพวกเขาจำนวนมากในรหัสของคุณ และเมื่อคอมไพเลอร์ทำงานหรือ interpitor (ขึ้นอยู่กับภาษาที่คุณใช้) มันจะไปยังฟังก์ชันนั้นในหน่วยความจำ ดังนั้นสมมติว่าคุณมี 3 ในนั้นฉันไม่คิดว่าคอมพิวเตอร์จะสังเกตเห็น แต่ถ้าคุณเริ่มมีสิ่งเล็ก ๆ น้อย ๆ 100 ชิ้นระบบจะต้องลงทะเบียนฟังก์ชั่นในหน่วยความจำที่เรียกเพียงครั้งเดียวแล้วไม่ถูกทำลาย


ตามที่คำตอบของสตีเฟ่นนี้อาจไม่เกิดขึ้นเสมอ (แม้ว่าไว้วางใจสุ่มสี่สุ่มห้าในเวทมนตร์คอมไพเลอร์ไม่สามารถที่ดีอยู่แล้ว)
vemv

1
ใช่มันควรจะถูกลบออกไปขึ้นอยู่กับข้อเท็จจริงมากมาย หากเป็นภาษา interpated ระบบจะล้มเหลวสำหรับฟังก์ชั่นบรรทัดเดียวทุกครั้งเว้นแต่ว่าคุณจะติดตั้งบางสิ่งบางอย่างสำหรับแคชซึ่งยังคงไม่สามารถหลอกลวงได้ ตอนนี้เมื่อพูดถึงคอมไพเลอร์มันก็แค่เรื่องวันที่อ่อนแอและความสงบของดาวเคราะห์ถ้าคอมไพเลอร์จะเป็นเพื่อนของคุณและกำจัดความยุ่งเหยิงเล็ก ๆ น้อย ๆ ของคุณหรือถ้าคิดว่าคุณต้องการมันจริงๆ ฉันจำได้ว่าถ้าคุณรู้จำนวนที่แน่นอนของการวนรอบจะทำงานได้ดีกว่าการคัดลอกและวางหลาย ๆ ครั้งเพื่อวนซ้ำ
WojonsTech

+1 สำหรับการจัดแนวดาวเคราะห์ :) แต่ประโยคสุดท้ายของคุณฟังดูเต็มไปหมดสำหรับฉันคุณทำอย่างนั้นจริงหรือ
vemv

มันขึ้นอยู่กับเวลาส่วนใหญ่ที่ฉันไม่ได้ทำเว้นแต่ฉันจะได้รับจำนวนเงินที่ถูกต้องเพื่อตรวจสอบว่ามันเพิ่มความเร็วและอื่น ๆ เช่นนั้นหรือไม่ แต่ในคอมไพเลอร์รุ่นเก่าควรคัดลอกและวางเพื่อให้คอมไพเลอร์คิดออก 9/10
WojonsTech

3

ฉันได้ทำสิ่งที่แน่นอนเมื่อเร็ว ๆ นี้ในแอปพลิเคชันที่ฉันได้รับการ refactoring เพื่อให้ความหมายที่แท้จริงของความคิดเห็นรหัส sans:

protected void PaymentButton_Click(object sender, EventArgs e)
    Func<bool> HaveError = () => lblCreditCardError.Text == string.Empty && lblDisclaimer.Text == string.Empty;

    CheckInputs();

    if(HaveError())
        return;

    ...
}

แค่อยากรู้ภาษานั้นคืออะไร?
vemv

5
@vemv: ดูเหมือน C # กับฉัน
Scott Mitchell

ฉันชอบตัวระบุพิเศษมากกว่าความคิดเห็น แต่สิ่งนี้แตกต่างจากการแนะนำตัวแปรท้องถิ่นเพื่อให้ifสั้นหรือไม่ วิธีการในท้องถิ่น (แลมบ์ดา) ทำให้PaymentButton_Clickฟังก์ชั่น (โดยรวม) อ่านยากขึ้น lblCreditCardErrorในตัวอย่างของคุณน่าจะเป็นสมาชิกจึงยังHaveErrorเป็น (ส่วนตัว) วินิจฉัยที่ถูกต้องสำหรับวัตถุ ฉันมักจะ downvote นี้ แต่ฉันไม่ใช่โปรแกรมเมอร์ C # ดังนั้นฉันต่อต้าน
Wolf

@ Wolf เฮ้ชายใช่ ฉันเขียนสิ่งนี้มาสักพักแล้ว :) ฉันทำสิ่งที่แตกต่างออกไปอย่างแน่นอนในวันนี้ ที่จริงแล้วการดูเนื้อหาฉลากเพื่อดูว่ามีข้อผิดพลาดหรือไม่ทำให้ฉันประจบประแจง ... ทำไมฉันไม่ส่งคืนบูลจากCheckInputs()???
joshperry

0

การย้ายที่หนึ่งบรรทัดเป็นวิธีที่มีชื่อดีทำให้โค้ดของคุณอ่านง่ายขึ้น คนอื่น ๆ หลายคนพูดถึงแล้วว่า ("รหัสเอกสารด้วยตนเอง") ข้อดีอีกอย่างของการย้ายมันไปยังวิธีการคือทำให้ง่ายต่อการทดสอบหน่วย เมื่อแยกเป็นวิธีของตัวเองและทดสอบหน่วยคุณสามารถมั่นใจได้ว่าหาก / เมื่อพบข้อผิดพลาดมันจะไม่อยู่ในวิธีนี้


0

แล้วมีจำนวนมากของคำตอบที่ดี แต่มีกรณีพิเศษมูลค่าการกล่าวขวัญ

หากคำสั่งแบบบรรทัดเดียวของคุณต้องการความคิดเห็นและคุณสามารถระบุวัตถุประสงค์ (ซึ่งหมายถึง: ชื่อ) ได้อย่างชัดเจนให้พิจารณาแยกฟังก์ชั่นในขณะที่เพิ่มความคิดเห็นลงในเอกสาร API วิธีนี้ทำให้การเรียกใช้ฟังก์ชันง่ายขึ้นเร็วขึ้นและเข้าใจได้ง่ายขึ้น

สิ่งที่น่าสนใจสามารถทำได้หากไม่มีสิ่งที่ต้องทำในขณะนี้ แต่ความคิดเห็นเตือนการขยายที่จำเป็น (ในอนาคตอันใกล้1 ), ดังนั้นสิ่งนี้

def sophisticatedHello():
    # todo set up
    say("hello")
    # todo tear down

สามารถเปลี่ยนเป็นสิ่งนี้ได้เช่นกัน

def sophisticatedHello():
    setUp()
    say("hello")
    tearDown()

1)คุณควรแน่ใจเกี่ยวกับเรื่องนี้จริงๆ (ดูหลักการYAGNI )


0

หากภาษารองรับฉันมักจะใช้ฟังก์ชั่นที่ไม่ระบุชื่อเพื่อทำสิ่งนี้ให้สำเร็จ

someCondition = lambda p: True if [complicated expression involving p] else False
#I explicitly write the function with a ternary to make it clear this is a a predicate
if (someCondition(p)):
    #do stuff...

IMHO นี่คือการประนีประนอมที่ดีเพราะมันจะช่วยให้คุณได้รับประโยชน์จากการอ่านไม่ได้มีการแสดงออกที่ซับซ้อนเกะกะifเงื่อนไขในขณะที่หลีกเลี่ยงความยุ่งเหยิงในโลก / แพคเกจ namespace ที่มีป้ายขนาดเล็กทิ้ง มันมีประโยชน์เพิ่มเติมที่ฟังก์ชั่น "คำจำกัดความ" ถูกต้องในที่ที่มันถูกใช้ทำให้ง่ายต่อการแก้ไขและอ่านคำจำกัดความ

มันไม่จำเป็นต้องทำหน้าที่ของกริยาเท่านั้น ฉันชอบที่จะห่อหุ้มแผ่นบอยเลอร์ซ้ำ ๆ ในฟังก์ชั่นขนาดเล็กเช่นนี้เช่นกัน (มันทำงานได้ดีเป็นพิเศษสำหรับการสร้างรายการไพ ธ อนโดยไม่ทำให้ไวยากรณ์ของวงเล็บเหลี่ยมยุ่งเหยิง) ตัวอย่างเช่นตัวอย่าง oversimplified ต่อไปนี้เมื่อทำงานกับ PIL ใน python

#goal - I have a list of PIL Image objects and I want them all as grayscale (uint8) numpy arrays
im_2_arr = lambda im: array(im.convert('L')) 
arr_list = [im_2_arr(image) for image in image_list]

ทำไม "lambda p: จริงถ้า [การแสดงออกที่ซับซ้อนที่เกี่ยวข้องกับ p] อื่นเท็จ" แทนที่จะเป็น "แลมบ์ดา p: [การแสดงออกที่ซับซ้อนที่เกี่ยวข้องกับ p]"? 8-)
Hans-Peter Störr

@hstoerr ในความคิดเห็นด้านล่างบรรทัดนั้น ฉันชอบที่จะทำให้เป็นที่รู้จักอย่างชัดเจนว่าเราบางคนสภาพอากาศเป็นคำกริยา ในขณะที่ไม่จำเป็นอย่างเคร่งครัดของผมเขียนมากสคริปต์วิทยาศาสตร์อ่านโดยคนที่ไม่ได้รหัสที่มากผมเองคิดว่ามันเหมาะสมกว่าที่จะมีรวบรัดพิเศษมากกว่ามีเพื่อนร่วมงานของฉันสับสนเพราะพวกเขาไม่ทราบว่า[] == Falseคนอื่น ๆ หรือบางส่วน การเทียบเท่า pythonic ที่คล้ายกันซึ่งไม่ 'ใช้งานง่าย' โดยพื้นฐานแล้วมันเป็นวิธีการตั้งค่าสถานะว่าเงื่อนไขบางอย่างในความเป็นจริงเป็นกริยา
crasic

เพื่อล้างความผิดพลาดที่เห็นได้ชัดของฉัน[] != Falseแต่[]เป็นเท็จเมื่อถูกส่งไปยังบูล
crasic

@crasic: เมื่อฉันไม่คาดหวังว่าผู้อ่านของฉันจะรู้ว่า [] ประเมินว่าเป็นเท็จฉันชอบทำlen([complicated expression producing a list]) == 0มากกว่าการใช้True if [blah] else Falseซึ่งยังคงต้องการให้ผู้อ่านรู้ว่า [] ประเมินเป็นเท็จ
S, โกหก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.