backticks มีความหมายอย่างไรกับตัวแปล python: "num"


89

ฉันกำลังเล่นกับความเข้าใจในรายการและฉันเจอตัวอย่างข้อมูลเล็ก ๆ น้อย ๆ นี้ในเว็บไซต์อื่น:

return ''.join([`num` for num in xrange(loop_count)])

ฉันใช้เวลาสองสามนาทีในการพยายามจำลองฟังก์ชัน (โดยการพิมพ์) ก่อนที่จะรู้ว่า`num`บิตนั้นพัง

การปิดคำสั่งในอักขระเหล่านั้นทำอะไร? จากสิ่งที่ฉันเห็นมันเทียบเท่ากับ str (num) แต่เมื่อฉันหมดเวลา:

return ''.join([str(num) for num in xrange(10000000)])

ใช้เวลา 4.09 วินาทีในขณะที่:

return ''.join([`num` for num in xrange(10000000)])

ใช้เวลา 2.43 วินาที

ทั้งสองให้ผลลัพธ์ที่เหมือนกัน แต่อย่างใดอย่างหนึ่งช้ากว่ามาก เกิดขึ้นที่นี่คืออะไร?

แก้ไข:ผิดปกติ ... repr()ให้ผลลัพธ์ช้ากว่า`num`. 2.99s เทียบกับ 2.43s ใช้ Python 2.6 (ยังไม่ได้ลอง 3.0)


8
หลังจากอ่าน "ไซต์อื่น" ที่skymind.com/~ocrow/python_stringฉันมีคำถามคล้าย ๆ กันและพบหน้านี้ คำถามที่ดีและคำตอบที่ดี :)
netvope

คำตอบ:


124

backticks repr()เป็นนามแฝงเลิกใช้ อย่าใช้มันอีกต่อไปไวยากรณ์ถูกลบออกใน Python 3.0

การใช้ backticks ดูเหมือนจะเร็วกว่าการใช้repr(num)หรือnum.__repr__()ในเวอร์ชัน 2.x ฉันเดาว่าเป็นเพราะต้องมีการค้นหาพจนานุกรมเพิ่มเติมในเนมสเปซส่วนกลาง (สำหรับrepr) หรือในเนมสเปซของวัตถุ (สำหรับ__repr__) ตามลำดับ


การใช้disโมดูลพิสูจน์สมมติฐานของฉัน:

def f1(a):
    return repr(a)

def f2(a):
    return a.__repr__()

def f3(a):
    return `a`

การแยกชิ้นส่วนการแสดง:

>>> import dis
>>> dis.dis(f1)
  3           0 LOAD_GLOBAL              0 (repr)
              3 LOAD_FAST                0 (a)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE
>>> dis.dis(f2)
  6           0 LOAD_FAST                0 (a)
              3 LOAD_ATTR                0 (__repr__)
              6 CALL_FUNCTION            0
              9 RETURN_VALUE        
>>> dis.dis(f3)
  9           0 LOAD_FAST                0 (a)
              3 UNARY_CONVERT       
              4 RETURN_VALUE   

f1เกี่ยวข้องกับการค้นหาทั่วโลกสำหรับrepr, f2ค้นหาที่แอตทริบิวต์สำหรับ__repr__ในขณะที่ผู้ประกอบการ backtick จะดำเนินการใน opcode แยกต่างหาก เนื่องจากไม่มีค่าใช้จ่ายสำหรับการค้นหาพจนานุกรม ( LOAD_GLOBAL/ LOAD_ATTR) หรือสำหรับการเรียกใช้ฟังก์ชัน ( CALL_FUNCTION) backticks จึงเร็วกว่า

ฉันเดาว่าชาว Python ตัดสินใจว่าการมีการดำเนินการระดับต่ำที่แยกจากกันrepr()นั้นไม่คุ้มค่าและการมีทั้งสองอย่างrepr()และการย้อนกลับเป็นการละเมิดหลักการ

"ควรมีวิธีเดียว - และควรมีเพียงวิธีเดียวเท่านั้นที่จะทำได้"

ดังนั้นคุณลักษณะนี้จึงถูกลบออกใน Python 3.0


ฉันต้องการค้นหาวิธีที่คุณสามารถแทนที่ backticks ด้วยการเรียกฟังก์ชันบางอย่าง แต่ดูเหมือนว่าจะเป็นไปไม่ได้หรือเป็นไปได้
Jiri

2
ใช้ repr () แทน backticks Backticks เป็นไวยากรณ์ที่คิดค่าเสื่อมราคาสำหรับ repr () มา 3.0 ฉันชอบรูปลักษณ์ของ backticks มากกว่าที่จะเรียกใช้ฟังก์ชัน ANOTHER
Dominic Bou-Samra

9
เหตุผลที่เลิกใช้ backticks ก็เป็นเพราะตัวละคร อาจเป็นเรื่องยากที่จะพิมพ์ (บนแป้นพิมพ์บางรุ่น) ยากที่จะมองเห็นว่ามันคืออะไรพิมพ์ยากในหนังสือ Python ฯลฯ
u0b34a0f6ae

4
@ kaizer.se: ขอบคุณที่ชี้ให้เห็น นี่อาจเป็นสาเหตุหลักในการทิ้งแบ็คทิกดูคำสั่ง Guidos ในที่เก็บรายชื่ออีเมล
Ferdinand Beyer

คำถามเดิมที่โพสต์คือเพราะฉันไม่พบ backticks บนแป้นพิมพ์ของฉันจริงๆ;) ด้านล่างตัวหนอนดูเหมือนว่าหลังจาก googling
Dominic Bou-Samra

10

Backtick quoting โดยทั่วไปไม่เป็นประโยชน์และหายไปใน Python 3

สำหรับสิ่งที่คุ้มค่าสิ่งนี้:

''.join(map(repr, xrange(10000000)))

เร็วกว่าเวอร์ชัน backtick สำหรับฉันเล็กน้อย แต่ความกังวลเกี่ยวกับเรื่องนี้อาจเป็นการเพิ่มประสิทธิภาพก่อนเวลาอันควร


2
เหตุใดจึงต้องถอยหลังและใช้แผนที่แทนความเข้าใจในรายการ / ตัววนซ้ำ
nikow

4
อันที่จริงให้timeitผลลัพธ์ที่เร็ว''.join(map(repr, xrange(0, 1000000)))กว่าสำหรับ''.join([repr(i) for i in xrange(0, 1000000)])(ยิ่งแย่ลงสำหรับ''.join( (repr(i) for i in xrange(0, 1000000)) )) มันน่าผิดหวังเล็กน้อย ;-)
RedGlyph

8
ผลลัพธ์ของ Bobince ไม่น่าแปลกใจสำหรับฉัน ตามหลักทั่วไปแล้วการวนซ้ำโดยปริยายใน Python นั้นเร็วกว่าอย่างชัดเจนซึ่งมักจะเร็วกว่าอย่างมาก mapถูกนำไปใช้ใน C โดยใช้ C loop ซึ่งเร็วกว่า Python loop ที่ดำเนินการในเครื่องเสมือนมาก
Ferdinand Beyer

7
ไม่แปลกใจเช่นกันมันแย่เกินไปสำหรับชื่อเสียงของรายการที่เข้าใจได้ (ตัวอย่างนี้มีการตี 30%) แต่ฉันอยากจะมีความชัดเจนมากกว่ารหัสความเร็วที่เห็นได้ชัดเว้นแต่สิ่งนี้จะสำคัญมากดังนั้นจึงไม่มีเรื่องใหญ่ที่นี่ ตามที่กล่าวไว้ฟังก์ชั่น map () ไม่ได้ทำให้ฉันไม่ชัดเจนบางครั้ง LC ก็เกินจริง
RedGlyph

4
mapดูเหมือนชัดเจนและกระชับสำหรับฉันและฉันไม่รู้ด้วยซ้ำว่า Python
Zenexer

1

ฉันเดาว่าnumไม่ได้กำหนดวิธีการ__str__()เพื่อให้มีการดำเนินการค้นหาแบบที่สองสำหรับstr()__repr__

backticks __repr__ดูโดยตรง หากเป็นเช่นนั้นการใช้repr()แทนแบ็กติกก็ควรให้ผลลัพธ์เหมือนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.