2.5. เมธอดสตริงและการจัดรูปแบบ

สตริงมาพร้อมกับกล่องเครื่องมือเมธอดในตัวสำหรับการตรวจสอบและการปรับรูป เนื่องจากสตริงเป็น immutable ทุกเมธอดจะคืนค่าสตริง ใหม่ -- ต้นฉบับไม่เปลี่ยนแปลง

2.5.1. การตรวจสอบสตริง

  • str.startswith() / str.endswith() -- ทดสอบคำนำหน้าหรือส่วนต่อท้าย คืนค่า bool

  • str.find() -- ตำแหน่งของการปรากฏครั้งแรกของสตริงย่อย หรือ -1 หากไม่พบ str.index() ทำงานเหมือนกันแต่เกิด ValueError เมื่อไม่พบ

  • str.count() -- จำนวนการปรากฏที่ไม่ทับซ้อนกัน

  • คีย์เวิร์ด in -- "MV" in name คืนค่า True หากสตริงย่อยอยู่ที่ใดก็ได้ในสตริง

>>> name = "OpenMV Cam"
>>> name.startswith("Open")
True
>>> name.find("MV")
4
>>> name.count("m")
1
>>> "Cam" in name
True

2.5.2. การทำความสะอาดและการแปลงตัวพิมพ์

  • str.strip() -- ลบช่องว่างนำหน้าและท้าย ส่งสตริงของตัวอักษรเพื่อลบชุดที่กำหนดเอง (s.strip("/"))

  • str.lower() / str.upper() -- การแปลงตัวพิมพ์

  • str.replace() -- การแทนที่สตริงย่อย

>>> "  hello  ".strip()
'hello'
>>> "abc-123".replace("-", "_")
'abc_123'
>>> "OpenMV".lower()
'openmv'

2.5.3. การแยกและการรวม

  • str.split() -- แยกสตริงเป็นรายการที่ทุกการปรากฏของตัวคั่น (ค่าเริ่มต้น: ช่องว่างใดก็ได้)

  • str.join() -- ผกผัน: เชื่อมลำดับของสตริงเข้าด้วยกันโดยใช้ตัวรับเป็นตัวคั่น นี่คือวิธีที่มีประสิทธิภาพในการสร้างสตริงยาวจากชิ้นส่วน

>>> "1,2,3".split(",")
['1', '2', '3']
>>> "hello world".split()
['hello', 'world']
>>> ", ".join(["a", "b", "c"])
'a, b, c'

2.5.4. f-strings

วิธีที่ง่ายที่สุดในการแทรกค่าลงในสตริงคือ f-string -- สตริงลิเทอรัลที่มีคำนำหน้า f นิพจน์ใดก็ตามภายใน {} จะถูกประเมินและแทรก:

>>> name = "OpenMV"
>>> count = 42
>>> f"{name} saw {count} blobs"
'OpenMV saw 42 blobs'

เครื่องหมายโคลอนภายในวงเล็บปีกกานำ format spec ที่ควบคุมการแสดงผลค่า:

  • {x:.2f} -- float ที่มีทศนิยม 2 ตำแหน่ง

  • {x:>10} -- ชิดขวาในช่องขนาด 10 ตัวอักษร

  • {x:<10} -- ชิดซ้าย

  • {x:0>4} -- เติมศูนย์นำหน้าให้กว้าง 4 ตัวอักษร

  • {x:#x} -- เลขฐานสิบหกพร้อมคำนำหน้า 0x

  • {x:b} -- การแสดงผลแบบเลขฐานสอง

>>> f"pi is roughly {3.14159:.3f}"
'pi is roughly 3.142'
>>> f"reg = {0xAB:#x}"
'reg = 0xab'
>>> for i in range(3):
...     print(f"line {i:0>3}")
line 000
line 001
line 002

เครื่องหมาย = เดี่ยวหลังชื่อนิพจน์จะพิมพ์ทั้งชื่อและค่า -- มีประโยชน์สำหรับการ debug อย่างรวดเร็ว:

>>> v = 3.14
>>> print(f"{v=}")
v=3.14

2.5.4.1. การแปลงฐานของจำนวนเต็ม

ฟังก์ชันในตัวสามตัวทำงานเหมือนกับ format spec :b / :o / :x แต่คืนค่าสตริงที่แปลงแล้วโดยตรง:

  • bin() -- ฐาน 2 พร้อมคำนำหน้า "0b"

  • oct() -- ฐาน 8 พร้อมคำนำหน้า "0o"

  • hex() -- ฐาน 16 พร้อมคำนำหน้า "0x"

>>> hex(255)
'0xff'
>>> bin(10)
'0b1010'
>>> oct(8)
'0o10'

ทิศทางผกผัน -- แปลงสตริงฐาน N กลับเป็นจำนวนเต็ม -- ใช้ตัวสร้าง int พร้อมฐานที่ระบุชัดเจน:

>>> int("ff", 16)
255
>>> int("0b1010", 2)         # the "0b" prefix is allowed
10

ใช้สิ่งเหล่านี้เมื่อต้องการสตริงดิบของ int (สำหรับบรรทัด log, ไฟล์ config, การดัมป์รีจิสเตอร์) ใช้ format spec เมื่อต้องการ padding, ความกว้าง, หรือการผสมค่ากับข้อความอื่นใน f-string เดียวกัน

2.5.5. สไตล์การจัดรูปแบบแบบเก่า

f-strings เป็นสไตล์ที่แนะนำ แต่สองวิธีแบบเก่ายังคงใช้งานได้และปรากฏในโค้ดที่มีอยู่:

str.format() -- วงเล็บปีกกาพร้อมอาร์กิวเมนต์ตำแหน่งหรือคีย์เวิร์ดที่ส่งให้เมธอด .format() บนสตริงเทมเพลต:

>>> "Hello, {}".format(name)
'Hello, OpenMV'
>>> "{0} + {0} = {1}".format(2, 4)
'2 + 2 = 4'
>>> "{name}: {value}".format(name="frames", value=42)
'frames: 42'

Format spec ({:.2f}, {:>10}, ...) ทำงานเหมือนกันกับใน f-strings ความแตกต่างเพียงอย่างเดียวคือ ที่ที่ ค่าถูกระบุ

การจัดรูปแบบแบบ % (printf-style) -- โอเปอเรเตอร์ % เดี่ยวแทนที่ค่าลงในรหัสรูปแบบ หนึ่งค่าต่อหนึ่งรหัส ส่งหลายค่าเป็น tuple:

>>> "Hello, %s" % name
'Hello, OpenMV'
>>> "%d + %d = %d" % (2, 2, 4)
'2 + 2 = 4'
>>> "%.2f" % 3.14159
'3.14'

รหัสประเภทที่พบบ่อยที่สุดคือ %s (สตริง), %d (จำนวนเต็ม), %f (float) และ %x (เลขฐานสิบหก)

รหัส % แต่ละตัวสามารถมีตัวปรับแต่งระหว่าง % และตัวอักษรประเภท รูปทรงเต็มคือ %[flags][width][.precision]type:

  • width -- จำนวนตัวอักษรขั้นต่ำที่ช่องต้องใช้ ค่าที่สั้นกว่าจะถูกเติมช่องว่าง ค่าที่ยาวกว่าจะล้น %10d จองตัวอักษร 10 ตัวและชิดขวาตัวเลข

  • precision -- ความหมายขึ้นอยู่กับประเภท สำหรับ float คือจำนวนหลักหลังจุดทศนิยม %.2f ให้ทศนิยมสองตำแหน่ง สำหรับสตริง คือจำนวนตัวอักษรสูงสุดที่จะนำมา (%.5s ตัดให้เหลือห้าตัวอักษร)

  • ชิดซ้าย -- แฟล็ก - วางช่องไว้ทางซ้าย %-10d วางตัวเลขไว้ด้านซ้ายพร้อม trailing space

  • Zero pad -- แฟล็ก 0 เติมศูนย์นำหน้าแทนช่องว่าง (สำหรับประเภทตัวเลข) %05d เติมศูนย์ให้ครบห้าหลัก

  • เครื่องหมาย -- แฟล็ก + แสดงเครื่องหมายบนตัวเลขเสมอ รวมถึง + สำหรับค่าบวก

  • รูปแบบสลับ -- แฟล็ก # สำหรับ %x จะเติมคำนำหน้า 0x ที่ผลลัพธ์ สำหรับ %o จะเติม 0o

Flags, width และ precision สามารถนำมาใช้ร่วมกันได้:

>>> "%10d" % 42
'        42'                 # width 10, space-padded, right-aligned
>>> "%-10d|" % 42
'42        |'                # width 10, left-aligned
>>> "%05d" % 42
'00042'                      # width 5, zero-padded
>>> "%8.2f" % 3.14159
'    3.14'                   # width 8, 2 decimal places
>>> "%08.2f" % 3.14159
'00003.14'                   # width 8, zero-padded
>>> "%+d" % 42
'+42'                        # explicit sign
>>> "%#06x" % 0xAB
'0x00ab'                     # 0x prefix, zero-pad to 6 chars total

ทั้งสองสไตล์แบบเก่าอ่านได้ช้ากว่าและมีโอกาสผิดพลาดมากกว่า f-strings -- ใช้ f-strings ในโค้ดใหม่ และจดจำสไตล์แบบเก่าเมื่ออ่านโค้ดที่มีอยู่