ฉันได้รับคำเตือน pep8 นี้ทุกครั้งที่ฉันใช้แลมบ์ดานิพจน์ ไม่แนะนำให้ใช้แลมบ์ดานิพจน์? ถ้าไม่ใช่เพราะอะไร
ฉันได้รับคำเตือน pep8 นี้ทุกครั้งที่ฉันใช้แลมบ์ดานิพจน์ ไม่แนะนำให้ใช้แลมบ์ดานิพจน์? ถ้าไม่ใช่เพราะอะไร
คำตอบ:
คำแนะนำในPEP-8 ที่คุณพบคือ:
ใช้คำสั่ง def เสมอแทนคำสั่งการมอบหมายที่ผูกแลมบ์ดานิพจน์กับชื่อโดยตรง
ใช่:
def f(x): return 2*x
No:
f = lambda x: 2*x
รูปแบบแรกหมายความว่าชื่อของวัตถุฟังก์ชั่นที่เกิดขึ้นเป็นพิเศษ 'f' แทนสามัญ '<lambda>' สิ่งนี้มีประโยชน์มากกว่าสำหรับการย้อนกลับและการแทนค่าสตริงโดยทั่วไป การใช้คำสั่งที่ได้รับมอบหมายช่วยลดผลประโยชน์เพียงอย่างเดียวที่แลมบ์ดาแสดงออกสามารถนำเสนอเหนือข้อความสั่งการที่ชัดเจน (เช่นสามารถฝังอยู่ภายในนิพจน์ที่ใหญ่กว่า)
การกำหนด lambdas ให้กับชื่อนั้นเป็นเพียงแค่การทำซ้ำการทำงานของdef
- และโดยทั่วไปแล้วมันเป็นการดีที่สุดที่จะทำบางสิ่งด้วยวิธีเดียวเพื่อหลีกเลี่ยงความสับสนและเพิ่มความชัดเจน
กรณีการใช้งานที่ถูกต้องสำหรับแลมบ์ดาเป็นที่ที่คุณต้องการใช้ฟังก์ชั่นโดยไม่ต้องกำหนดเช่น:
sorted(players, key=lambda player: player.rank)
โดยทั่วไปแล้วอาร์กิวเมนต์หลักในการทำเช่นนี้คือdef
ข้อความสั่งนั้นจะส่งผลให้มีบรรทัดของโค้ดมากขึ้น คำตอบหลักของฉันคือ: ใช่และนั่นก็ดี การเว้นจำนวนบรรทัดให้น้อยที่สุดไม่ใช่สิ่งที่คุณควรทำ: ไปเพื่อความชัดเจนในระยะสั้น
def
ผ่านตัวตรวจสอบ PEP8 คุณจะได้รับE704 multiple statements on one line (def)
และถ้าคุณแบ่งออกเป็นสองบรรทัดคุณจะได้รับE301 expected 1 blank line, found 0
: - /
นี่คือเรื่องราวฉันมีฟังก์ชั่นแลมบ์ดาที่ฉันใช้สองครั้ง
a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)
นี่เป็นเพียงการนำเสนอฉันได้เผชิญหน้ากับรุ่นนี้สองสามรุ่น
ตอนนี้เพื่อรักษาสิ่งที่แห้งฉันเริ่มที่จะนำแลมบ์ดากลับมาใช้ใหม่อีกครั้ง
f = lambda x : x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
ณ จุดนี้ตัวตรวจสอบคุณภาพรหัสของฉันบ่นเกี่ยวกับแลมบ์ดาว่าเป็นฟังก์ชั่นที่ตั้งชื่อดังนั้นฉันจึงแปลงมันเป็นฟังก์ชั่น
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
ตอนนี้ตัวตรวจสอบบ่นว่าฟังก์ชั่นจะต้องถูกล้อมรอบด้วยหนึ่งบรรทัดว่างก่อนและหลัง
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
ที่นี่เรามีรหัส 6 บรรทัดแทนที่จะเป็น 2 บรรทัดต้นฉบับโดยไม่เพิ่มความสามารถในการอ่านและไม่มีการเพิ่มขึ้นของการเป็นแบบ pythonic ณ จุดนี้ผู้ตรวจสอบรหัสบ่นเกี่ยวกับฟังก์ชั่นที่ไม่มีเอกสาร
ในความเห็นของฉันกฎนี้ควรหลีกเลี่ยงและเสียเมื่อมันเหมาะสมใช้วิจารณญาณของคุณ
a = [x + offset for x in simple_list]
. ไม่จำเป็นต้องใช้map
และlambda
ที่นี่
x + offset
ส่วนไปยังตำแหน่งที่เป็นนามธรรมที่สามารถปรับปรุงได้โดยไม่ต้องเปลี่ยนรหัสมากกว่าหนึ่งบรรทัด ด้วยความเข้าใจในรายการตามที่คุณกล่าวถึงคุณจะยังคงต้องการโค้ดสองบรรทัดที่อยู่x + offset
ในรายการตอนนี้ เพื่อที่จะดึงผู้ที่ออกมาเป็นผู้เขียนต้องการคุณจะต้องมีหรือdef
lambda
def
และlambda
หนึ่งยังสามารถใช้functools.partial : แล้วf = partial(operator.add, offset)
a = list(map(f, simple_list))
def f(x): return x + offset
(เช่นฟังก์ชั่นง่าย ๆ ที่กำหนดไว้ในบรรทัดเดียว)? อย่างน้อยกับ flake8 ฉันไม่ได้รับการร้องเรียนเกี่ยวกับบรรทัดว่าง
a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)]
Lattyware ถูกต้องแน่นอน: โดยทั่วไปแล้วPEP-8ต้องการให้คุณหลีกเลี่ยงสิ่งต่างๆ
f = lambda x: 2 * x
และแทนที่จะใช้
def f(x):
return 2 * x
อย่างไรก็ตามในขณะที่การแก้ไขในเร็ว ๆ นี้รายงานข้อบกพร่อง (สิงหาคม 2014) งบเช่นต่อไปนี้อยู่ในขณะนี้สอดคล้อง:
a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x
เนื่องจากตัวตรวจสอบ PEP-8 ของฉันยังไม่สามารถใช้งานได้อย่างถูกต้องฉันจึงปิด E731 ในขณะนั้น
def
ตัวตรวจสอบ PEP8 ก็บ่นE301 expected 1 blank line, found 0
ดังนั้นคุณต้องเพิ่มบรรทัดว่างที่น่าเกลียดไว้ข้างหน้า
ฉันยังพบสถานการณ์ที่เป็นไปไม่ได้ที่จะใช้ฟังก์ชั่น def (ined)
class SomeClass(object):
# pep-8 does not allow this
f = lambda x: x + 1 # NOQA
def not_reachable(self, x):
return x + 1
@staticmethod
def also_not_reachable(x):
return x + 1
@classmethod
def also_not_reachable(cls, x):
return x + 1
some_mapping = {
'object1': {'name': "Object 1", 'func': f},
'object2': {'name': "Object 2", 'func': some_other_func},
}
ในกรณีนี้ฉันต้องการทำแผนที่ที่เป็นของชั้นเรียนจริงๆ วัตถุบางอย่างในการทำแผนที่จำเป็นต้องมีฟังก์ชั่นเดียวกัน มันจะไม่มีเหตุผลที่จะใส่ฟังก์ชั่นที่มีชื่อนอกชั้นเรียน ฉันไม่พบวิธีการอ้างถึงวิธี (staticmethod, classmethod หรือ normal) จากภายในร่างกายของชั้นเรียน SomeClass ยังไม่มีเมื่อเรียกใช้รหัส ดังนั้นการอ้างอิงจากชั้นเรียนจึงเป็นไปไม่ได้เช่นกัน
also_not_reachable
ในคำจำกัดความการทำแผนที่เป็นSomeClass.also_not_reachable
f
ทั้ง 2.7 และ 3.5 สำหรับฉัน
@staticmethod
และ@classmethod
ไม่ต้องการวัตถุเพียงSomeClass.also_not_reachable
(แม้ว่าพวกเขาต้องการชื่อเฉพาะ) หากคุณต้องการเข้าถึงจากวิธีการเรียนเพียงใช้self.also_not_reachable
*not_reachable
วิธีการเป็นnot_as_easily_reachable_from_class_definition_as_a_lambda
xD
flake8
( flake8.pycqa.org )