φυβλαςのβλογ
phyblas的博客



ภาษา python เบื้องต้น บทที่ ๔: พื้นฐานเรื่องฟังก์ชัน
เขียนเมื่อ 2016/03/03 22:50
แก้ไขล่าสุด 2024/02/22 10:59
 



ความหมายของฟังก์ชัน

คำว่าฟังก์ชัน (function) เป็นคำที่น่าจะเคยได้ยินอยู่บ่อยๆ แต่คำนี้จริงๆมีความหมายอยู่หลากหลายมาก ขึ้นอยู่กับว่าคุยกันเรื่องอะไร

หลายคนอาจเคยได้ยินคำนี้ครั้งแรกกันตอนเรียนคณิตศาสตร์ชั้นมัธยมศึกษา

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


ในที่นี้ เป็นฟังก์ชัน และ x คืออาร์กิวเมนต์ของฟังก์ชัน

อาร์กิวเมนต์ คือค่าที่อยู่ในวงเล็บหลังฟังก์ชัน เป็นค่าที่ป้อนให้กับฟังก์ชัน เพื่อให้ฟังก์ชันนำค่านั้นไปดำเนินการทำอะไรบางอย่าง

ในที่นี้หากป้อนค่า x เป็น 0.5 ค่านี้ก็จะถูกนำไปคำนวณ


ผลที่ได้คือฟังก์ชันนี้คืน 0.1 ออกมา ค่า 0.1 นี้จะเรียกว่าค่าคืนกลับ (return)

ฟังก์ชันในทางภาษาคอมพิวเตอร์ก็มีลักษณะคล้ายกันนี้ คือใส่ค่าอะไรบางอย่าง (อาร์กิวเมนต์) ลงไปแล้วก็จะมีค่าคืนกลับออกมา

ในบทที่แล้วได้พูดถึงคำสั่ง int float str bool ซึ่งใช้แปลงชนิดของข้อมูลเพื่อให้เป็นชนิดตามนั้น โดยใส่ข้อมูลชนิดเก่าลงไปแล้วได้ค่าคืนกลับเป็นข้อมูลชนิดใหม่ เช่น
a = 1.111
b = int(a)
print(b) # ได้ 1

ในตัวอย่างนี้ a เป็นจำนวนจริงซึ่งมีเลขทศนิยม แต่ใช้คำสั่ง int เพื่อแปลงเป็นจำนวนเต็มแล้วคืนค่ากลับมาแล้วเก็บค่าไว้ใน b ผลก็คือ b ได้ค่าเป็น 1 โดยเศษถูกปัดทิ้งหมด

คำสั่งที่ใช้แปลงชนิดข้อมูลเหล่านี้ถือว่าเป็นฟังก์ชันชนิดหนึ่งในภาษาไพธอน

***ที่จริงหากว่ากันในรายละเอียดจริงๆแล้ว int float str bool เป็นชื่อคลาส (ชื่อชนิดข้อมูล) อย่างไรก็ตามชื่อคลาสสามารถใช้ทำหน้าที่เหมือนเป็นฟังก์ชันเพื่อสร้างออบเจกต์ในคลาสนั้นอยู่แล้ว จึงถือว่าเป็นฟังก์ชันด้วย

หรืออีกตัวอย่างหนึ่งคือฟังก์ชันที่ชือว่า len ซึ่งมีไว้สำหรับหาความยาวของสายอักขระ
len('sawatdi') # ได้ 7

ในที่นี้ 'sawatdi' เป็นอาร์กิวเมนต์ของฟังก์ชัน len แล้ว 7 เป็นค่าคืนกลับที่ได้มา

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

เช่นคำสั่ง print ซึ่งใช้มาตั้งแต่บทที่ ๒ แล้ว ก็ถือเป็นฟังก์ชันชนิดหนึ่ง ซึ่งกรณีของ print นั้น อาร์กิวเมนต์ที่ใส่เข้าไปคือสิ่งที่เราต้องการให้แสดงผลออกมา เช่น
print('sawatdi')

ในที่นี้ 'sawatdi' คืออาร์กิวเมนต์ เมื่อใส่ลงไปในฟังก์ชัน print ฟังก์ชันก็จะทำข้อความไปแสดงผลออกมาทางหน้าจอ

จะเห็นว่าไม่ว่าฟังก์ชันไหนก็ตาม จะมีรูปแบบเหมือนกันก็คือ ชื่อฟังก์ชัน ตามด้วยวงเล็บเปิดและปิด ( ) ซึ่งภายในวงเล็บจะใส่อาร์กิวเมนต์ที่ฟังก์ชันต้องการ

และฟังก์ชันก็จะนำค่าอาร์กิวเมนต์ไปทำอะไรบางอย่างและอาจมีการคืนค่ากลับมาหรือไม่ก็ได้

อีกอย่างที่ต้องเน้นสักหน่อยก็คืออาร์กิวเมนต์อาจเป็นค่าข้อมูลหรือตัวแปรที่เก็บข้อมูลอยู่ก็ได้

ตัวแปรที่ถูกใช้เป็นอาร์กิวเมนต์ในฟังก์ชันมักจะไม่มีการเปลี่ยนแปลงอะไร แค่ถูกนำค่าไปใช้เท่านั้น เช่น
c = 2.222
d = str(c)
print(d) # ได้ '2.222'
print(c) # ได้ 2.222

จะเห็นว่า c ถูกใช้ในฟังก์ชัน str เพื่อให้ได้ค่า d เป็นสายอักขระ แต่ว่า c ก็ยังเป็นตัวเลขอยู่เหมือนเดิมไม่เปลี่ยนแปลง

อย่างไรก็ตาม ฟังก์ชันที่ทำให้เกิดความเปลี่ยนแปลงกับอาร์กิวเมนต์ที่ใส่เข้าไปก็มีอยู่เช่นกัน



อาร์กิวเมนต์หลายตัว

อาร์กิวเมนต์ไม่จำเป็นที่จะต้องมีแค่ตัวเดียว อาจมีหลายตัวก็ได้ หากมีหลายตัวก็ต้องคั่นด้วยเครื่องหมายจุลภาค , เช่น
print('a =', 1, ', b =', 2) # ได้ a = 1 , b = 2

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

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



คีย์เวิร์ดของฟังก์ชัน

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

ยกตัวอย่างการใช้คีย์เวิร์ดในฟังก์ชัน print
print('ฉันมีความสุข','555','๕๕๕','อยากหัวเราะดังๆ',sep='(^_^)')

ผลลัพธ์
ฉันมีความสุข(^_^)555(^_^)๕๕๕(^_^)อยากหัวเราะดังๆ

ตัวอย่าง นี้จะเห็นว่าประกอบไปด้วยอาร์กิวเมนต์ ๔ ตัว และด้านหลังอาร์กิวเมนต์ หลังจุลภาคตัวสุดท้ายจะเห็น sep='(^_^)' ซึ่ง sep นี้ก็คือคีย์เวิร์ดที่ใส่เพิ่มลงไปนั่นเอง

ความหมายของ sep ในฟังก์ชัน print ก็คือคำที่ใช้แยกระหว่างอาร์กิวเมนต์แต่ละตัวที่ใส่ลงไป ดังนั้นจึงจะเห็นได้ว่ามี (^_^) ปรากฏขึ้นมาแทรก

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

นอกจาก sep แล้วก็ยังมีคีย์เวิร์ดสำคัญอีกตัวคือ end ซึ่งเป็นตัวกำหนดการสิ้นสุดประโยค
print('การฝึกฝนที่ไม่มีความเจ็บปวดมันไม่มีความหมาย',end=' ')
print('เพราะคนเราไม่สามารถได้อะไรมาโดยที่ไม่ต้องเสียสละอะไร',end=' ')
print('แต่ว่าเมื่อทนความเจ็บปวดนั้นและก้าวผ่านมันไปได้',end='')
print('ถึงตอนนั้นคนเราก็จะมีจิตใจที่แกร่งกล้าไม่แพ้ใครๆ',end='!')
(ที่มาของประโยค)

ผลลัพธ์
การฝึกฝนที่ไม่มีความเจ็บปวดมันไม่มีความหมาย เพราะคนเราไม่สามารถได้อะไรมาโดยที่ไม่ต้องเสียสละอะไร แต่ว่าเมื่อทนความเจ็บปวดนั้นและก้าวผ่านมันไปได้ถึงตอนนั้นคนเราก็จะมี จิตใจที่แกร่งกล้าไม่แพ้ใครๆ!

โดยปกติแล้วถ้าไม่ใส่คีย์เวิร์ด end ลงไปพอจบฟังก์ชัน print จะมีการขึ้นบรรทัดใหม่นั่นเพราะโดยปกติถูกกำหนดให้สิ้นสุดด้วย \n ซึ่งหมายถึงขึ้นบรรทัดใหม่ แต่ถ้าใส่ end ลงไปเราจะสามารถเปลี่ยนเป็นจบด้วยอะไรก็ได้ ถ้าต้องการให้ติดกันเลยก็พิมพ์ ''
***ทั้ง sep และ end ใช้ได้เฉพาะไพธอน 3 ส่วนไพธอน 2 จะใช้วิธีที่ต่างกันออกไป
>>> รายละเอียด



การคืนกลับและการส่งออก

มีอีกเรื่องที่พูดถึงไปแล้วเล็กน้อยในบทที่ ๒ แต่ก็ควรต้องนำมากล่าวย้ำตรงนี้ด้วย นั่นคือความแตกต่างระหว่างระหว่างการคืนกลับ (return) และการส่งออก (output) ซึ่งอาจสร้างความสับสนได้

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

ส่วนการส่งออกนั้นหมายถึงการที่ค่านั้นถูกนำออกมาแสดงผล ให้เราได้เห็น โดยทั่วไปคือออกมาบนหน้าจอ เป็นข้อความ ซึ่งการส่งออกที่พื้นฐานที่สุดก็คือการใช้ฟังก์ชัน print

ฟังก์ชัน print นั้นไม่ได้ทำให้เกิดค่าอะไรคืนกลับมาแต่แค่ทำหน้าที่ส่งออกค่าที่เราป้อนเข้าไปให้

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

เช่นหากพิมพ์ float('129.3') ในเชลก็จะได้ค่า 129.3 ออกมาพร้อมแสดงออกมาทันทีโดยไม่ต้องใช้ print

อย่างไรก็ตาม ความจริงแล้วการแสดงผลค่าคืนกลับผ่านทางเชลนั้นไม่ได้เหมือนฟังก์ชัน print เสมอไป และฟังก์ชันที่สามารถส่งออกข้อมูลมาแสดงผลได้ก็ไม่ได้มีแต่ print ซึ่งตรงนี้จะค่อยมาพูดกันต่อไป



ฟังก์ชัน input

สิ่งที่ตรงข้ามกับการส่งออกข้อมูลก็คือการป้อนเข้า (input)

ในภาษาไพธอนฟังก์ชันที่ใช้ในการป้อนเข้าข้อมูลชื่อฟังก์ชัน input

ตัวอย่างการใช้ ลองพิมพ์ตามนี้ลงในเชล
a = input()

เสร็จแล้วโปรแกรมก็จะให้เราพิมพ์ข้อความอะไรบางอย่างใส่เพิ่มลงไป ก็ให้พิมพ์อะไรก็ได้ลงไปแล้วกด enter

เสร็จแล้วข้อความที่ใส่ลงไปนั้นก็จะถูกเก็บอยู่ในตัวแปร a

จากนั้นลองใช้คำสั่ง print เพื่อพิมพ์สิ่งที่เก็บอยู่ในตัวแปร a ออกมา
print('a คือ',a)

ก็จะได้ข้อความที่เราพิมพ์ลงไปนั้นออกมา

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

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

ในตัวอย่างข้างต้นจะเห็นว่าในวงเล็บหลัง input นั้นว่างเปล่า ไม่ได้ใส่อะไรลงไป แต่ที่จริงแล้วฟังก์ชัน input เองก็สามารถใส่อาร์กิวเมนต์ลงไปได้ ซึ่งพอใส่ลงไปแล้ว สิ่งนั้นจะกลายเป็น ข้อความที่เราต้องการให้แสดงผลออกมาก่อนที่จะให้ป้อนข้อความ

โดยทั่วไปเหมือนเป็นข้อความที่ใช้บอกให้ผู้ใช้รู้ว่าจะต้องป้อนอะไร ขอยกตัวอย่างการใช้ เช่น ลองพิมพ์
a = input('จงป้อนค่าอะไรสักอย่าง: ')

จากนั้นก็จะมีข้อความขึ้นว่า
จงป้อนค่าอะไรสักอย่าง:

แล้วจึงตามด้วยส่วนที่ให้พิมพ์ข้อความอยู่ทางขวาของข้อความ

การทำงานของ input ก็เป็นอย่างที่เห็นนี้ อาจชวนให้สับสนได้ง่าย ต้องจำไว้ว่าข้อความในอาร์กิวเมนต์ของ input เป็นเพียงแค่ข้อความที่สื่อสารกับผู้ใช้ว่าควรจะกรอกข้อมูลอะไร แต่ไม่ได้มีผลอะไรกับข้อมูลที่ป้อนเข้าไป

สิ่งที่ต้องเน้นอีกอย่างคือ ข้อมูลที่ป้อนเข้าไปด้วยฟังก์ชัน input นี้จะเป็นสายอักขระ หากต้องการจะได้ค่าเป็นจำนวนจริงหรือจำนวนเต็มก็จะต้องแปลงอีกที เช่น
a = float(input('จงป้อนตัวเลขลงไป: '))

จากนั้นก็ลองป้อนค่าตัวเลขอะไรบางอย่างเข้าไป

แต่ถ้าป้อนค่าที่ไม่ใช่ตัวเลขลงไปเช่นใส่ตัวหนังสือปนลงไปด้วยก็จะขัดข้องทันที

***ทั้งหมดที่ว่ามานี้ในไพธอน 2 จะมีความแตกต่างออกไปพอสมควร
>>> รายละเอียด



เมธอด

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

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

เวลาเขียนเมธอดจะเขียนตามหลังวัตถุที่ต้องการใช้เมธอดนั้น โดยใช้จุด . คั่น

ขอยกตัวอย่างเช่น ออบเจ็กต์ชนิดจำนวนจริงมีเมธอดที่ชื่อว่า is_integer() คือเมธอดสำหรับตรวจว่าค่าของจำนวนจริงนั้นเป็นจำนวนเต็มในทางคณิตศาสตร์หรือ ไม่ (คือมีค่าเลขทศนิยมเป็น 0 หรือไม่) ถ้าเป็นก็คืนค่า True ถ้าไม่ใช่ก็คืนค่า False
x = 3.0
x.is_integer() # ได้ผลเป็น True

แต่
(3.1).is_integer() # ได้ผลเป็น False

แต่ถ้าใช้เมธอดกับวัตถุผิดชนิด
(3).is_integer() # จะได้ AttributeError: 'int' object has no attribute 'is_integer'

เพราะข้อมูลชนิดจำนวนเต็มไม่มีเมธอด is_integer ต้องเป็นข้อมูลชนิดจำนวนจริงเท่านั้นถึงจะมี

วงเล็บที่อยู่ด้านหลังนั้นสามารถใส่อาร์กิวเมนต์หรือคีย์เวิร์ดลงไปได้เช่นกันหากเมธอดนั้นเป็นเมธอดที่ต้องการหรือสามารถใส่เพิ่มอาร์กิวเมนต์หรือคีย์เวิร์ดได้



สรุปเนื้อหา
  • ฟังก์ชันคือสิ่งที่ทำให้เกิดการดำเนินการทำอะไรบางอย่าง หรืออาจคืนค่าอะไรบางอย่างกลับออกมา
  • คลาสหรือชนิดของข้อมูล เช่น int float str bool นั้นไม่ใช่ฟังก์ชันโดยตรงแต่ก็สามารถทำหน้าที่เหมือนฟังก์ชัน โดยมีหน้าที่แปลงชนิดข้อมูลให้กลายเป็นคลาสนั้น
  • ฟังก์ชันจะต้องลงท้ายด้วยวงเล็บ () และอาจมีอาร์กิวเมนต์หรือคีย์อยู่ภายใน
  • ส่วนเมธอดคือฟังก์ชันที่จำเพาะต่อออบเจ็กต์แต่ละชนิด เวลาใช้จะต้องเขียนตามหลังวัตถุโดยคั่นด้วยจุด . และต้องมีวงเล็บ () ต่อท้ายเช่นกัน

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



อ้างอิง




-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python

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

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ