ค่า None คืออะไร


130

ฉันศึกษา Python อยู่และฉันอ่านบทหนึ่งซึ่งอธิบายถึงNoneคุณค่า แต่น่าเสียดายที่หนังสือเล่มนี้ยังไม่ชัดเจนเท่าที่ควร ฉันคิดว่าฉันจะหาคำตอบสำหรับคำถามของฉันถ้าฉันแบ่งปันที่นั่น

ฉันต้องการทราบว่าNoneมูลค่าคืออะไรและคุณใช้เพื่ออะไร

และฉันก็ไม่ได้เป็นส่วนหนึ่งของหนังสือเล่มนี้:

การกำหนดค่าNoneให้กับตัวแปรเป็นวิธีหนึ่งในการรีเซ็ตเป็นสถานะเดิมที่ว่างเปล่า

นั่นหมายความว่าอย่างไร?

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

การกำหนดค่าNoneให้กับตัวแปรเป็นวิธีหนึ่งในการรีเซ็ตเป็นสถานะเดิมที่ว่างเปล่า

สุดท้าย:

ในที่สุดฉันก็ได้รับคำตอบจากการค้นหาคำตอบที่ต่างออกไป ฉันต้องขอบคุณทุกคนที่ให้เวลาเพื่อช่วยเหลือฉัน (โดยเฉพาะ Martijn Pieters และ DSM) และฉันหวังว่าฉันจะสามารถเลือกคำตอบทั้งหมดให้ดีที่สุด แต่การเลือกนั้น จำกัด ไว้ที่หนึ่ง คำตอบทั้งหมดนั้นยอดเยี่ยมมาก


39
หนังสือเล่มนั้นไม่เป็นประโยชน์ Noneไม่ใช่สถานะว่างดีฟอลต์สำหรับตัวแปร
Martijn Pieters

ปิดด้านบนของหัวของฉัน php เป็นภาษาเดียวที่มีค่าเป็นโมฆะเทียบเท่ากับสถานะที่ว่างเปล่าเริ่มต้นสำหรับตัวแปร ตอนนี้ฉันสงสัยว่าภาษาอื่นทำอะไร
kojiro

@kojiro Perl undefแม้ว่าจะไม่มีความเท่าเทียมกันของผู้ประกอบการมีความสุขเกี่ยวกับการเปรียบเทียบกับ นอกจากนี้ยังมีเนื้อหา javascript, แม้ว่ามันจะมีทั้งและnull undefined
Eevee

ค่าเริ่มต้นของตัวแปร @kojiro javascript คือundefinedถ้าไม่มีการกำหนดค่าใหม่
thefourtheye

ใช่ซึ่งแตกต่างจากnullจุดที่ฉันไม่สามารถทำกับ @MartijnPieters ในคำตอบของเขา
kojiro

คำตอบ:


99

คำตอบของ Martijn อธิบายสิ่งที่Noneอยู่ใน Python และระบุอย่างถูกต้องว่าหนังสือเล่มนี้ทำให้เข้าใจผิด ตั้งแต่โปรแกรมเมอร์ Python ตามกฎจะไม่พูด

การกำหนดค่าNoneให้กับตัวแปรเป็นวิธีหนึ่งในการรีเซ็ตเป็นสถานะเดิมที่ว่างเปล่า

เป็นการยากที่จะอธิบายความหมายของ Briggs ในแบบที่สมเหตุสมผลและอธิบายว่าทำไมไม่มีใครในที่นี้รู้สึกมีความสุขกับมัน การเปรียบเทียบที่อาจช่วยได้:

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

F = "fork"

คุณใส่สติกเกอร์ "F" "fork"บนวัตถุสตริง ถ้าคุณเขียนแล้ว

F = None

คุณย้ายสติกเกอร์ไปที่Noneวัตถุ

สิ่งที่บริกส์จะขอให้คุณจินตนาการว่าคุณไม่ได้เขียนสติกเกอร์"F"มีอยู่แล้วFสติกเกอร์บนNoneและสิ่งที่คุณไม่ได้ย้ายก็จากไปNone "fork"ดังนั้นเมื่อคุณพิมพ์F = Noneที่คุณกำลัง "ตั้งค่า [ติ๋ง] มันเดิมรัฐว่างเปล่า" ถ้าเราตัดสินใจที่จะรักษาเป็นความหมายNoneempty state

ฉันสามารถเห็นสิ่งที่เขาได้รับ แต่นั่นเป็นวิธีที่ไม่ดีในการดู ถ้าคุณเริ่ม Python และพิมพ์print(F)คุณจะเห็น

>>> print(F)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'F' is not defined

และนั่นNameErrorหมายถึงงูใหญ่ไม่รู้จักชื่อF, เพราะไม่มีสติกเกอร์ดังกล่าว ถ้าบริกส์ถูกต้องและF = Noneรีเซ็ตFเป็นสถานะดั้งเดิมมันควรจะอยู่ที่นั่นตอนนี้และเราควรเห็น

>>> print(F)
None

เหมือนที่เราทำหลังจากที่เราพิมพ์และนำสติกเกอร์บนF = NoneNone


นั่นคือทั้งหมดที่เกิดขึ้น ในความเป็นจริงงูใหญ่มาพร้อมกับสติกเกอร์บางแนบมาแล้วกับวัตถุ (built-in ชื่อ) แต่คนอื่น ๆ ที่คุณต้องเขียนเองมีเส้นเหมือนF = "fork"และA = 2และc17 = 3.14และจากนั้นคุณสามารถติดพวกเขาในวัตถุอื่น ๆ ในภายหลัง (ชอบF = 10หรือF = Noneมันเป็นเหมือนกันทั้งหมด .)

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


1
ขอโทษ แต่คุณหมายถึงอะไรโดย Briggs คุณหมายถึงผู้แต่งหนังสือเล่มนี้หรือไม่เพราะชื่อของเขาคือ Jason R. Briggs
The_Diver

@The_Diver: ใช่นั่นคือเขา
DSM

ฉันจะหาข้อมูลเพิ่มเติมเกี่ยวกับชื่อในตัวของไพ ธ อนได้ที่ไหนขอบคุณ
The_Diver

3
นี่เป็นคำอธิบายที่ดีสำหรับผู้ที่ไม่ใช่โปรแกรมเมอร์ ขอบคุณมาก!
Christina

67

Noneเป็นเพียงค่าที่ใช้โดยทั่วไปเพื่อระบุว่า 'ว่างเปล่า' หรือ 'ไม่มีค่าที่นี่' มันเป็นวัตถุสัญญาณ ; มันมีความหมายเพียงเพราะเอกสาร Python บอกว่ามันมีความหมายนั้น

มีเพียงหนึ่งสำเนาของวัตถุนั้นในเซสชันล่าม Python ที่กำหนด

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

คุณสามารถทดสอบได้อย่างชัดเจน:

if foo is None:
    # foo is set to None

if bar is not None:
    # bar is set to something *other* than None

การใช้งานอื่นคือการให้พารามิเตอร์ทางเลือกให้กับฟังก์ชั่นเริ่มต้น 'ว่าง':

def spam(foo=None):
    if foo is not None:
        # foo was specified, do something clever!

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

ภาษาอื่นมีแนวคิดที่คล้ายกัน SQL มีNULL; JavaScript มีundefined และ nullอื่น ๆ

โปรดทราบว่าใน Python ตัวแปรมีอยู่โดยอาศัยการใช้ คุณไม่จำเป็นต้องประกาศตัวแปรก่อนดังนั้นจึงไม่มีตัวแปรที่ว่างเปล่าใน Python การตั้งค่าตัวแปรให้Noneไม่ใช่สิ่งเดียวกันกับการตั้งค่าเป็นค่าเริ่มต้นที่ว่างเปล่า Noneเป็นค่าด้วยเช่นกันแม้ว่าจะใช้เพื่อส่งสัญญาณความว่างเปล่า หนังสือที่คุณกำลังอ่านกำลังทำให้เข้าใจผิดในจุดนั้น


1
ฉันคิดว่าความหมายของความว่างเปล่านั้นแตกต่างจากความไม่แน่นอน ดังนั้นฉันไม่แน่ใจว่าจาวาสคริปต์และคู่ของ SQL กำลังชี้แจง - พวกเขาอาจสร้างความสับสนให้กับปัญหา มีทั้ง JavaScript และundefined null
kojiro

@kojiro: undefinedเป็นวัตถุใน JavaScript และคุณสามารถใช้วัตถุนั้นอย่างชัดเจนเหมือนกับที่คุณสามารถใช้Noneใน Python มันเป็นวัตถุสัญญาณที่มีความหมายเดียวกันมาก
Martijn Pieters

@kojiro: SQL ไม่ใช่ภาษาการเขียนโปรแกรม แต่NULLยังคงเป็นสิ่งที่สามารถกำหนดและทดสอบอย่างชัดเจน
Martijn Pieters

5
@MartijnPieters: SQL เป็นภาษาการเขียนโปรแกรมเพียงจุดประสงค์ที่เฉพาะเจาะจงมากหนึ่งประกาศ
danielkza

3
@daniel: SQL มีคุณสมบัติเป็นภาษาการเขียนโปรแกรมได้รับการอภิปรายนาน ... ดูstackoverflow.com/questions/900055/…สำหรับมุมที่น่าสนใจ
Martijn Pieters

23

นี่คือสิ่งที่เอกสาร Pythonได้กล่าวถึงNone:

ค่าเดียวของ types.NoneType ไม่มีการใช้บ่อยครั้งเพื่อแสดงถึงการไม่มีค่าเช่นเดียวกับเมื่ออาร์กิวเมนต์เริ่มต้นไม่ถูกส่งผ่านไปยังฟังก์ชัน

เปลี่ยนเป็นเวอร์ชั่น 2.4: การมอบหมายเป็นไม่มีผิดกฎหมายและเพิ่ม SyntaxError

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

  1. ขอยืนยันประเภทของNoneก่อน

    print type(None)
    print None.__class__

    เอาท์พุต

    <type 'NoneType'>
    <type 'NoneType'>

โดยทั่วไปNoneTypeเป็นประเภทข้อมูลที่เหมือนintและfloatอื่น ๆ คุณสามารถตรวจสอบรายการประเภทเริ่มต้นที่มีอยู่ใน Python ใน8.15 types - ชื่อสำหรับประเภทในตัว

  1. และNoneเป็นตัวอย่างของการNoneTypeเรียน ดังนั้นเราอาจต้องการสร้างอินสแตนซ์ของNoneตัวเราเอง มาลองดูกัน

    print types.IntType()
    print types.NoneType()

    เอาท์พุต

    0
    TypeError: cannot create 'NoneType' instances

ชัดเจนไม่สามารถสร้างNoneTypeอินสแตนซ์ได้ Noneเราไม่ต้องกังวลเกี่ยวกับความเป็นเอกลักษณ์ของค่า

  1. ตรวจสอบวิธีการที่เราใช้งานNoneภายใน

    print dir(None)

    เอาท์พุต

    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
     '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

ยกเว้น__setattr__คนอื่น ๆ ทั้งหมดเป็นคุณลักษณะแบบอ่านอย่างเดียว Noneดังนั้นไม่มีทางที่เราสามารถปรับเปลี่ยนลักษณะของไม่มี

  1. ลองและเพิ่มคุณสมบัติใหม่ไปที่ None

    setattr(types.NoneType, 'somefield', 'somevalue')
    setattr(None, 'somefield', 'somevalue')
    None.somefield = 'somevalue'

    เอาท์พุต

    TypeError: can't set attributes of built-in/extension type 'NoneType'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    AttributeError: 'NoneType' object has no attribute 'somefield'

ข้อความที่เห็นด้านบนสร้างข้อความแสดงข้อผิดพลาดตามลำดับ หมายความว่าเราไม่สามารถสร้างคุณลักษณะในแบบไดนามิกNoneได้

  1. Noneขอให้เราตรวจสอบสิ่งที่เกิดขึ้นเมื่อเรากำหนดบางสิ่งบางอย่าง SyntaxErrorตามเอกสารก็ควรโยน หมายความว่าหากเรากำหนดบางสิ่งให้Noneกับโปรแกรมจะไม่ถูกดำเนินการเลย

    None = 1

    เอาท์พุต

    SyntaxError: cannot assign to None

เราได้พิสูจน์แล้วว่า

  1. None เป็นตัวอย่างของ NoneType
  2. None ไม่สามารถมีแอตทริบิวต์ใหม่
  3. คุณลักษณะที่มีอยู่ของNoneไม่สามารถเปลี่ยนแปลงได้
  4. เราไม่สามารถสร้างอินสแตนซ์อื่น ๆ ของ NoneType
  5. เราไม่สามารถเปลี่ยนการอ้างอิงถึงNoneด้วยการกำหนดค่าให้กับมัน

ดังนั้นเป็นที่กล่าวถึงในเอกสารนี้สามารถจริงๆจะถือว่าเป็นNonetrue constant

มีความสุขรู้None:)


น่าสนใจมาก ๆ !! หนึ่งสงสัยในสิ่งที่มีประโยชน์__setattr__สำหรับไม่มี
Grijesh Chauhan

9

หนังสือที่คุณอ้างถึงนั้นพยายามที่จะทำให้ความหมายของมันง่ายขึ้นมาก Noneตัวแปรงูใหญ่ไม่ได้มีการเริ่มต้นของรัฐว่างเปล่า - ตัวแปรหลามจะผูกพัน (เท่านั้น) เมื่อพวกเขากำลังที่กำหนดไว้ คุณไม่สามารถสร้างตัวแปร Python โดยไม่ให้ค่า

>>> print(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> def test(x):
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes exactly 1 argument (0 given)
>>> def test():
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
NameError: global name 'x' is not defined

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

>>> def test(x=None):
...   if x is None:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

ความจริงที่ว่าค่านี้เป็นค่าพิเศษNoneไม่สำคัญอย่างยิ่งในกรณีนี้ ฉันสามารถใช้ค่าเริ่มต้นใด ๆ ได้:

>>> def test(x=-1):
...   if x == -1:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

… แต่การได้Noneอยู่รอบ ๆ ทำให้เราได้รับประโยชน์สองอย่าง:

  1. เราไม่จำเป็นต้องเลือกคุณค่าพิเศษเหมือน-1ความหมายที่ไม่ชัดเจนและ
  2. ฟังก์ชั่นของเราอาจจำเป็นต้องจัดการ-1เป็นอินพุตปกติ
>>> test(-1)
no x here

โอ๊ะ!

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

>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

5

คำตอบอื่น ๆ ได้อธิบายความหมายของNoneเรียบร้อยแล้ว อย่างไรก็ตามฉันยังต้องการที่จะเพิ่มความสว่างให้กับสิ่งนี้โดยใช้ตัวอย่าง

ตัวอย่าง:

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

ทีนี้ลองเดาผลลัพธ์ของรายการด้านบน ดีคำตอบเป็นที่น่าแปลกใจเป็นด้านล่าง:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

แต่ทำไม

หลายคนคาดหวังว่าlist1จะไม่ถูกต้องเท่ากับ[10]และlist3จะเท่ากับ['a']โดยคิดว่าอาร์กิวเมนต์ของรายการจะถูกตั้งค่าเป็นค่าเริ่มต้นของ[]ในแต่ละครั้งที่เรียกว่าextList

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

list1และlist3จึงทำงานในรายการเริ่มต้นเดียวกันในขณะที่list2ทำงานบนรายการแยกต่างหากที่สร้างขึ้น (โดยส่งรายการว่างเปล่าของตัวเองเป็นค่าสำหรับพารามิเตอร์รายการ)


'ไม่มี' ผู้ช่วยให้รอด: (แก้ไขตัวอย่างข้างต้นเพื่อให้เกิดพฤติกรรมที่ต้องการ)

def extendList(val, list=None):
    if list is None:
       list = []
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

ด้วยการดำเนินการแก้ไขนี้ผลลัพธ์จะเป็น:

list1 = [10]
list2 = [123]
list3 = ['a']

หมายเหตุ - ตัวอย่างเครดิต toptal.com


3

ไม่มีเป็นวัตถุเดี่ยว (หมายถึงมีเพียงหนึ่งไม่มี) ใช้ในหลายสถานที่ในภาษาและห้องสมุดเพื่อเป็นตัวแทนของค่าอื่น ๆ


ตัวอย่างเช่น
ถ้าdเป็นพจนานุกรมที่d.get(k)จะกลับมาd[k]ถ้ามันมีอยู่ แต่Noneถ้ามีที่สำคัญไม่มีdk

อ่านข้อมูลนี้จากบล็อกยอดเยี่ยม: http://python-history.blogspot.in/


3

ทั้งหมดนี้เป็นคำตอบที่ดี แต่ฉันคิดว่ามีมากกว่าที่จะอธิบายว่าทำไมจึงNoneมีประโยชน์

ลองนึกภาพคุณรวบรวม RSVPs ไปงานแต่งงาน คุณต้องการบันทึกว่าแต่ละคนจะเข้าร่วมหรือไม่ person.attending = Trueหากพวกเขาจะเข้าร่วมการประชุมที่คุณตั้งไว้ person.attending = Falseหากพวกเขาจะไม่ได้เข้าร่วมคุณชุด หากคุณยังไม่ได้รับการตอบกลับใด ๆ person.attending = Noneแล้ว ด้วยวิธีนี้คุณสามารถแยกแยะความแตกต่างระหว่างไม่มีข้อมูล - None- และคำตอบเชิงลบ


1

ฉันชอบตัวอย่างโค้ด (รวมถึงผลไม้) ดังนั้นให้ฉันแสดงให้คุณเห็น

apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None

ไม่มีความหมายอะไรมันไม่มีค่า

ไม่มีใครประเมินว่าเป็นเท็จ


8
print(None)พิมพ์ None.. มันจะไม่ได้ตามที่คุณแนะนำอะไรพิมพ์
Martijn Pieters

REPL ไม่แสดงอะไรเลยNoneหากเป็นผลลัพธ์ของการแสดงออกครั้งสุดท้าย (ซึ่งส่วนใหญ่มีประโยชน์สำหรับฟังก์ชั่นที่ไม่ต้องการคืนค่า)
Eevee

อืมข้อผิดพลาดของฉันฉันใช้ IDLE และฉันคิดว่ามันพิมพ์ตัวแปร ขณะนี้ฉันใช้ SO เพื่อพัฒนาทักษะการอ่านและทำความเข้าใจหลาม / จาวาสคริปต์ / โค้ดให้สมบูรณ์ดังนั้นฉันจึงทำผิดพลาด :(
Azeirah

2
IDLE เช่นพรอมต์ล่าม Python แบบโต้ตอบซ่อนไว้ อย่างชัดเจนNoneว่าเป็นผลของการแสดงออกส่วนใหญ่จะไม่ถ่วงเอาท์พุท
Martijn Pieters

-5
largest=none
smallest =none 
While True :
          num =raw_input ('enter a number ') 
          if num =="done ": break 
          try :
           inp =int (inp) 
          except:
              Print'Invalid input' 
           if largest is none :
               largest=inp
           elif inp>largest:
                largest =none 
           print 'maximum', largest

          if smallest is none:
               smallest =none
          elif inp<smallest :
               smallest =inp
          print 'minimum', smallest 

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