ฉันจะตรวจสอบว่าวัตถุ Python เป็นสตริง (ปกติหรือ Unicode) ได้อย่างไร
ฉันจะตรวจสอบว่าวัตถุ Python เป็นสตริง (ปกติหรือ Unicode) ได้อย่างไร
คำตอบ:
วิธีตรวจสอบว่าวัตถุo
เป็นชนิดสตริงของคลาสย่อยของชนิดสตริงหรือไม่:
isinstance(o, basestring)
เพราะทั้งสองstr
และเป็นคลาสย่อยunicode
basestring
ในการตรวจสอบว่าประเภทของo
ถูกต้องหรือไม่str
:
type(o) is str
ในการตรวจสอบว่าo
เป็นอินสแตนซ์ของstr
หรือคลาสย่อยของstr
:
isinstance(o, str)
ดังกล่าวข้างต้นยังทำงานสำหรับสตริง Unicode ถ้าคุณแทนที่ด้วยstr
unicode
อย่างไรก็ตามคุณอาจไม่จำเป็นต้องทำการตรวจสอบประเภทอย่างชัดเจนเลย "การพิมพ์เป็ด" อาจเหมาะกับความต้องการของคุณ ดูhttp://docs.python.org/glossary.html#term-duck-typing
basestring
ใน py2
ใน Python 3.x basestring
ไม่สามารถใช้งานได้อีกต่อไปเช่นstr
เดียวกับประเภทสตริง (ที่มีความหมายของ Python 2.x unicode
)
ดังนั้นการตรวจสอบใน Python 3.x จึงเป็นเพียง:
isinstance(obj_to_test, str)
นี้ต่อไปนี้การแก้ไขอย่างเป็นทางการ2to3
เครื่องมือการแปลง: แปลงไปbasestring
str
หากคุณต้องการตรวจสอบโดยไม่คำนึงถึงเวอร์ชัน Python (2.x vs 3.x) ให้ใช้six
( PyPI ) และstring_types
แอตทริบิวต์ของมัน:
import six
if isinstance(obj, six.string_types):
print('obj is a string!')
ภายในsix
(โมดูลไฟล์เดียวที่มีน้ำหนักเบามาก) เพียงทำสิ่งนี้ :
import sys
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str
else:
string_types = basestring
basestring
str
Egdef is_string(obj): try: return isinstance(obj, basestring) # python 2 except NameError: return isinstance(obj, str) # python 3
ฉันพบสิ่งนี้มากกว่าpythonic
:
if type(aObject) is str:
#do your stuff here
pass
ตั้งแต่ประเภทวัตถุเดี่ยว, จะสามารถนำมาใช้ในการทำเปรียบเทียบวัตถุรูปแบบ str
isinstance(obj_to_test, str)
มีความหมายอย่างชัดเจนในการทดสอบประเภทและมีความได้เปรียบในการใช้ขั้นตอนเดียวกับกรณีอื่น ๆ ที่ไม่ใช่ str
ถ้าใครอยากจะอยู่ห่างจากที่ชัดเจนประเภทการตรวจสอบ (และมีมีเหตุผลที่ดีที่จะอยู่ห่างจากมัน) น่าจะเป็นส่วนที่ปลอดภัยที่สุดของโปรโตคอลสตริงเพื่อเช็คอินคือ:
str(maybe_string) == maybe_string
มันจะไม่วนซ้ำผ่าน iterable หรือ iterator มันจะไม่เรียก list-of-strings สตริงและตรวจพบstringlikeเป็นสตริงอย่างถูกต้อง
แน่นอนว่ามีข้อเสียคือ ตัวอย่างเช่นstr(maybe_string)
อาจเป็นการคำนวณที่หนักหน่วง จึงมักจะเป็นคำตอบคือมันขึ้นอยู่กับ
แก้ไข: ตามที่@Tcll ชี้ให้เห็นในความคิดเห็นคำถามจะถามหาวิธีในการตรวจสอบทั้งสตริง Unicode และ bytestrings ใน Python 2 คำตอบนี้จะล้มเหลวโดยมีข้อยกเว้นสำหรับสตริง unicode ที่มีอักขระที่ไม่ใช่ ASCII และใน Python 3 จะมีการคืนค่าFalse
การทดสอบทั้งหมด
b = b'test'; r = str(b) == b
ซึ่งb
เก็บข้อมูลเดียวกันเป็นstr(b)
แต่ (เป็นวัตถุไบต์) ไม่ตรวจสอบเป็นสตริง
ในการตรวจสอบว่าตัวแปรของคุณเป็นอะไรที่คุณควรทำ:
s='Hello World'
if isinstance(s,str):
#do something here,
ผลลัพธ์ของ isistance จะให้ค่าบูลีนจริงหรือเท็จเพื่อให้คุณสามารถปรับเปลี่ยนได้ตามความเหมาะสม คุณสามารถตรวจสอบตัวย่อที่คาดหวังของค่าของคุณโดยเริ่มต้นใช้: type (s) ซึ่งจะส่งกลับคุณพิมพ์ 'str' เพื่อให้คุณสามารถใช้มันในฟังก์ชั่น isistance
ฉันอาจจัดการกับเรื่องนี้ในรูปแบบการพิมพ์เป็ดเหมือนคนอื่น ๆ พูดถึง ฉันจะรู้ได้อย่างไรว่าสตริงเป็นสตริงจริงๆ? อย่างชัดเจนโดยการแปลงเป็นสตริง!
def myfunc(word):
word = unicode(word)
...
หาก arg เป็นสตริงหรือยูนิโค้ดอยู่แล้ว real_word จะเก็บค่าไว้โดยไม่แก้ไข หากวัตถุที่ผ่านการใช้__unicode__
วิธีการที่ใช้ในการรับการเป็นตัวแทนของ Unicode หากไม่สามารถใช้วัตถุที่ส่งเป็นสตริงได้unicode
บิวด์อินจะยกข้อยกเว้น
isinstance(your_object, basestring)
จะเป็นจริงถ้าวัตถุของคุณเป็นประเภทสตริง 'str' เป็นคำที่สงวนไว้
คำขอโทษของฉันคำตอบที่ถูกต้องคือใช้ 'basestring' แทน 'str' เพื่อให้รวมสตริง unicode ด้วย - ดังที่ได้กล่าวไว้ข้างต้นโดยหนึ่งในผู้เผชิญเหตุอื่น ๆ
เย็นนี้ฉันวิ่งเข้าไปในสถานการณ์ที่ฉันคิดว่าฉันจะต้องตรวจสอบกับstr
ประเภท แต่มันกลับกลายเป็นว่าฉันไม่ได้
วิธีการของฉันในการแก้ปัญหาอาจจะใช้ได้ในหลาย ๆ สถานการณ์ดังนั้นฉันขอเสนอด้านล่างในกรณีที่ผู้อื่นที่อ่านคำถามนี้สนใจ (Python 3 เท่านั้น)
# NOTE: fields is an object that COULD be any number of things, including:
# - a single string-like object
# - a string-like object that needs to be converted to a sequence of
# string-like objects at some separator, sep
# - a sequence of string-like objects
def getfields(*fields, sep=' ', validator=lambda f: True):
'''Take a field sequence definition and yield from a validated
field sequence. Accepts a string, a string with separators,
or a sequence of strings'''
if fields:
try:
# single unpack in the case of a single argument
fieldseq, = fields
try:
# convert to string sequence if string
fieldseq = fieldseq.split(sep)
except AttributeError:
# not a string; assume other iterable
pass
except ValueError:
# not a single argument and not a string
fieldseq = fields
invalid_fields = [field for field in fieldseq if not validator(field)]
if invalid_fields:
raise ValueError('One or more field names is invalid:\n'
'{!r}'.format(invalid_fields))
else:
raise ValueError('No fields were provided')
try:
yield from fieldseq
except TypeError as e:
raise ValueError('Single field argument must be a string'
'or an interable') from e
การทดสอบบางอย่าง:
from . import getfields
def test_getfields_novalidation():
result = ['a', 'b']
assert list(getfields('a b')) == result
assert list(getfields('a,b', sep=',')) == result
assert list(getfields('a', 'b')) == result
assert list(getfields(['a', 'b'])) == result
มันง่ายใช้รหัสต่อไปนี้ (เราถือว่าวัตถุที่กล่าวถึงเป็น obj) -
if type(obj) == str:
print('It is a string')
else:
print('It is not a string.')
คุณสามารถทดสอบได้โดยต่อกับสตริงว่าง:
def is_string(s):
try:
s += ''
except:
return False
return True
แก้ไข :
การแก้ไขคำตอบของฉันหลังจากความคิดเห็นชี้ให้เห็นว่าสิ่งนี้ล้มเหลวด้วยรายการ
def is_string(s):
return isinstance(s, basestring)
สำหรับแนวทางการพิมพ์เป็ดที่ดีสำหรับการกดสตริงที่มีโบนัสในการทำงานกับทั้ง Python 2.x และ 3.x:
def is_string(obj):
try:
obj + ''
return True
except TypeError:
return False
wisefishอยู่ใกล้กับเป็ดพิมพ์ก่อนที่เขาจะเปลี่ยนไปisinstance
วิธีการยกเว้นว่า+=
มีความหมายที่แตกต่างกันสำหรับรายการกว่า+
ไม่
isalpha
แต่ใครจะรู้วิธีการที่ปลอดภัยที่จะมองหา?
try
สามารถเร็วขึ้น หากคุณคาดหวัง 99% ของเวลาอาจจะไม่ ความแตกต่างด้านประสิทธิภาพนั้นน้อยมากจะดีกว่าถ้าคุณใช้รหัสและระบุว่าช้า
if type(varA) == str or type(varB) == str:
print 'string involved'
จาก EDX - MITx หลักสูตรออนไลน์: 6.00.1x วิทยาการคอมพิวเตอร์เบื้องต้นและการเขียนโปรแกรมโดยใช้ Python
str
!