|
偶然发现一个python字符串的现象:>>>a='123_abc'>>>b='123_abc'>>>aisbTrue>>>c='abc#123'>>>d='abc#123'>>>cisdFalse这是为什么呢,原来它们的id不一样。>>>id(a)==id(b)True>>>id(c)==id(d)False那为什么它们的地址有的相同,有的不同呢?查询后得知这是一种Python的字符串驻留机制。字符串驻留机制也称为字符串常量优化(stringinterning),是一种在Python解释器中自动进行的优化过程。它主要目的是减少内存的使用,提高程序的运行效率。工作原理小字符串:Python只会对短小的字符串进行驻留。但是,这个长度并不是固定的,它可能会因Python的不同版本或实现而有所不同。字符串池(StringPool):Python解释器维护一个字符串池,用于存储所有已经出现过的字符串常量。驻留(Interning):当解释器遇到一个新的字符串字面量时,它会首先检查这个字符串是否已经存在于字符串池中。如果存在,则直接使用池中的引用;如果不存在,就将这个字符串添加到池中,并返回这个字符串的引用。内存节省:由于相同的字符串字面量在程序中可能被多次使用,通过字符串驻留机制,可以确保这些重复的字符串只存储一次,从而节省内存。性能提升:字符串比较操作可以通过比较它们的引用地址来完成,这比逐字符比较要快得多。因此,字符串驻留可以提高字符串比较的性能。自动和透明:字符串驻留是自动进行的,程序员不需要显式地进行任何操作。Python解释器会在后台处理这一过程。不可变类型:字符串驻留机制只适用于不可变类型,因为可变类型的对象内容可能会改变,这会使得引用地址比较失去意义。如果字符串可以修改,那么驻留机制可能会导致意外的副作用。限制:字符串驻留机制虽然有诸多好处,但也存在一些限制。例如,如果程序中使用了大量的动态生成的字符串,那么字符串驻留可能不会带来太大的好处,因为这些字符串可能不会被重复使用。字符串字面量:只有当字符串是字面量时,Python才会尝试进行驻留。通过其他方式(如str()函数、字符串拼接等)创建的字符串通常不会被驻留。编译时驻留:字符串驻留是在Python源代码编译成字节码时进行的,而不是在运行时。这意味着在运行时动态生成的字符串通常不会被驻留。显式驻留Python提供了一个sys库函数intern(),允许程序员显式地将一个字符串驻留。使用这个函数可以手动控制字符串的驻留过程:>>>fromsysimportintern>>>s=intern('abc#123')>>>t=intern('abc#123')>>>sistTrue>>>s='abc#123'>>>t='abc#123'>>>sistFalse>>>a=intern('abc_123')>>>b='abc_123'>>>aisbTrue字符串长短的分界小字符串才进行驻留,具体多少长度是界线也没有细查,大概用二分法也能枚举出来。>>>x='abcdefghijklmnopqrstuvwxyz'*100>>>y='abcdefghijklmnopqrstuvwxyz'*100>>>xisyTrue>>>x='abcdefghijklmnopqrstuvwxyz'*200>>>y='abcdefghijklmnopqrstuvwxyz'*200>>>xisyFalse>>>x='abcdefghijklmnopqrstuvwxyz'*150>>>y='abcdefghijklmnopqrstuvwxyz'*150>>>xisyTrue>>>x='abcdefghijklmnopqrstuvwxyz'*175>>>y='abcdefghijklmnopqrstuvwxyz'*175>>>xisyFalse......附:字符串方法(版本python3.12)capitalize(self,/) Returnacapitalizedversionofthestring. Morespecifically,makethefirstcharacterhaveuppercaseandtherestlower case.casefold(self,/) Returnaversionofthestringsuitableforcaselesscomparisons.center(self,width,fillchar='',/) Returnacenteredstringoflengthwidth.  addingisdoneusingthespecifiedfillcharacter(defaultisaspace).count(...) S.count(sub[,start[,end]])->int Returnthenumberofnon-overlappingoccurrencesofsubstringsubin stringS[start:end]. Optionalargumentsstartandendare interpretedasinslicenotation.encode(self,/,encoding='utf-8',errors='strict') Encodethestringusingthecodecregisteredforencoding. encoding Theencodinginwhichtoencodethestring. errors Theerrorhandlingschemetouseforencodingerrors. Thedefaultis'strict'meaningthatencodingerrorsraisea UnicodeEncodeError. Otherpossiblevaluesare'ignore','replace'and 'xmlcharrefreplace'aswellasanyothernameregisteredwith codecs.register_errorthatcanhandleUnicodeEncodeErrors.endswith(...) S.endswith(suffix[,start[,end]])->bool ReturnTrueifSendswiththespecifiedsuffix,Falseotherwise. Withoptionalstart,testSbeginningatthatposition. Withoptionalend,stopcomparingSatthatposition. suffixcanalsobeatupleofstringstotry.expandtabs(self,/,tabsize=8) Returnacopywherealltabcharactersareexpandedusingspaces. Iftabsizeisnotgiven,atabsizeof8charactersisassumed.find(...) S.find(sub[,start[,end]])->int ReturnthelowestindexinSwheresubstringsubisfound, suchthatsubiscontainedwithinS[start:end]. Optional argumentsstartandendareinterpretedasinslicenotation. Return-1onfailure.format(...) S.format(*args,**kwargs)->str ReturnaformattedversionofS,usingsubstitutionsfromargsandkwargs. Thesubstitutionsareidentifiedbybraces('{'and'}').format_map(...) S.format_map(mapping)->str ReturnaformattedversionofS,usingsubstitutionsfrommapping. Thesubstitutionsareidentifiedbybraces('{'and'}').index(...) S.index(sub[,start[,end]])->int ReturnthelowestindexinSwheresubstringsubisfound, suchthatsubiscontainedwithinS[start:end]. Optional argumentsstartandendareinterpretedasinslicenotation. RaisesValueErrorwhenthesubstringisnotfound.isalnum(self,/) ReturnTrueifthestringisanalpha-numericstring,Falseotherwise. Astringisalpha-numericifallcharactersinthestringarealpha-numericand thereisatleastonecharacterinthestring.isalpha(self,/) ReturnTrueifthestringisanalphabeticstring,Falseotherwise. Astringisalphabeticifallcharactersinthestringarealphabeticandthere isatleastonecharacterinthestring.isascii(self,/) ReturnTrueifallcharactersinthestringareASCII,Falseotherwise. ASCIIcharactershavecodepointsintherangeU+0000-U+007F. EmptystringisASCIItoo.isdecimal(self,/) ReturnTrueifthestringisadecimalstring,Falseotherwise. Astringisadecimalstringifallcharactersinthestringaredecimaland thereisatleastonecharacterinthestring.isdigit(self,/) ReturnTrueifthestringisadigitstring,Falseotherwise. Astringisadigitstringifallcharactersinthestringaredigitsandthere isatleastonecharacterinthestring.isidentifier(self,/) ReturnTrueifthestringisavalidPythonidentifier,Falseotherwise. Callkeyword.iskeyword(s)totestwhetherstringsisareservedidentifier, suchas"def"or"class".islower(self,/) ReturnTrueifthestringisalowercasestring,Falseotherwise. Astringislowercaseifallcasedcharactersinthestringarelowercaseand thereisatleastonecasedcharacterinthestring.isnumeric(self,/) ReturnTrueifthestringisanumericstring,Falseotherwise. Astringisnumericifallcharactersinthestringarenumericandthereisat leastonecharacterinthestring.isprintable(self,/) ReturnTrueifthestringisprintable,Falseotherwise. Astringisprintableifallofitscharactersareconsideredprintablein repr()orifitisempty.isspace(self,/) ReturnTrueifthestringisawhitespacestring,Falseotherwise. Astringiswhitespaceifallcharactersinthestringarewhitespaceandthere isatleastonecharacterinthestring.istitle(self,/) ReturnTrueifthestringisatitle-casedstring,Falseotherwise. Inatitle-casedstring,upper-andtitle-casecharactersmayonly followuncasedcharactersandlowercasecharactersonlycasedones.isupper(self,/) ReturnTrueifthestringisanuppercasestring,Falseotherwise. Astringisuppercaseifallcasedcharactersinthestringareuppercaseand thereisatleastonecasedcharacterinthestring.join(self,iterable,/) Concatenateanynumberofstrings. Thestringwhosemethodiscalledisinsertedinbetweeneachgivenstring. Theresultisreturnedasanewstring. Example:'.'.join(['ab','pq','rs'])->'ab.pq.rs'ljust(self,width,fillchar='',/) Returnaleft-justifiedstringoflengthwidth.  addingisdoneusingthespecifiedfillcharacter(defaultisaspace).lower(self,/) Returnacopyofthestringconvertedtolowercase.lstrip(self,chars=None,/) Returnacopyofthestringwithleadingwhitespaceremoved. IfcharsisgivenandnotNone,removecharactersincharsinstead.partition(self,sep,/)  artitionthestringintothreepartsusingthegivenseparator. Thiswillsearchfortheseparatorinthestring. Iftheseparatorisfound, returnsa3-tuplecontainingthepartbeforetheseparator,theseparator itself,andthepartafterit. Iftheseparatorisnotfound,returnsa3-tuplecontainingtheoriginalstring andtwoemptystrings.removeprefix(self,prefix,/) Returnastrwiththegivenprefixstringremovedifpresent. Ifthestringstartswiththeprefixstring,returnstring[len(prefix):]. Otherwise,returnacopyoftheoriginalstring.removesuffix(self,suffix,/) Returnastrwiththegivensuffixstringremovedifpresent. Ifthestringendswiththesuffixstringandthatsuffixisnotempty, returnstring[:-len(suffix)].Otherwise,returnacopyoftheoriginal string.replace(self,old,new,count=-1,/) Returnacopywithalloccurrencesofsubstringoldreplacedbynew. count Maximumnumberofoccurrencestoreplace. -1(thedefaultvalue)meansreplacealloccurrences. Iftheoptionalargumentcountisgiven,onlythefirstcountoccurrencesare replaced.rfind(...) S.rfind(sub[,start[,end]])->int ReturnthehighestindexinSwheresubstringsubisfound, suchthatsubiscontainedwithinS[start:end]. Optional argumentsstartandendareinterpretedasinslicenotation. Return-1onfailure.rindex(...) S.rindex(sub[,start[,end]])->int ReturnthehighestindexinSwheresubstringsubisfound, suchthatsubiscontainedwithinS[start:end]. Optional argumentsstartandendareinterpretedasinslicenotation. RaisesValueErrorwhenthesubstringisnotfound.rjust(self,width,fillchar='',/) Returnaright-justifiedstringoflengthwidth.  addingisdoneusingthespecifiedfillcharacter(defaultisaspace).rpartition(self,sep,/)  artitionthestringintothreepartsusingthegivenseparator. Thiswillsearchfortheseparatorinthestring,startingattheend.If theseparatorisfound,returnsa3-tuplecontainingthepartbeforethe separator,theseparatoritself,andthepartafterit. Iftheseparatorisnotfound,returnsa3-tuplecontainingtwoemptystrings andtheoriginalstring.rsplit(self,/,sep=None,maxsplit=-1) Returnalistofthesubstringsinthestring,usingsepastheseparatorstring. sep Theseparatorusedtosplitthestring. WhensettoNone(thedefaultvalue),willsplitonanywhitespace character(including\n\r\t\fandspaces)andwilldiscard emptystringsfromtheresult. maxsplit Maximumnumberofsplits(startingfromtheleft). -1(thedefaultvalue)meansnolimit. Splittingstartsattheendofthestringandworkstothefront.rstrip(self,chars=None,/) Returnacopyofthestringwithtrailingwhitespaceremoved. IfcharsisgivenandnotNone,removecharactersincharsinstead.split(self,/,sep=None,maxsplit=-1) Returnalistofthesubstringsinthestring,usingsepastheseparatorstring. sep Theseparatorusedtosplitthestring. WhensettoNone(thedefaultvalue),willsplitonanywhitespace character(including\n\r\t\fandspaces)andwilldiscard emptystringsfromtheresult. maxsplit Maximumnumberofsplits(startingfromtheleft). -1(thedefaultvalue)meansnolimit. Note,str.split()ismainlyusefulfordatathathasbeenintentionally delimited. Withnaturaltextthatincludespunctuation,considerusing theregularexpressionmodule.splitlines(self,/,keepends=False) Returnalistofthelinesinthestring,breakingatlineboundaries. Linebreaksarenotincludedintheresultinglistunlesskeependsisgivenand true.startswith(...) S.startswith(prefix[,start[,end]])->bool ReturnTrueifSstartswiththespecifiedprefix,Falseotherwise. Withoptionalstart,testSbeginningatthatposition. Withoptionalend,stopcomparingSatthatposition. prefixcanalsobeatupleofstringstotry.strip(self,chars=None,/) Returnacopyofthestringwithleadingandtrailingwhitespaceremoved. IfcharsisgivenandnotNone,removecharactersincharsinstead.swapcase(self,/) Convertuppercasecharacterstolowercaseandlowercasecharacterstouppercase.title(self,/) Returnaversionofthestringwhereeachwordistitlecased. Morespecifically,wordsstartwithuppercasedcharactersandallremaining casedcharactershavelowercase.translate(self,table,/) Replaceeachcharacterinthestringusingthegiventranslationtable. table Translationtable,whichmustbeamappingofUnicodeordinalsto Unicodeordinals,strings,orNone. Thetablemustimplementlookup/indexingvia__getitem__,forinstancea dictionaryorlist. IfthisoperationraisesLookupError,thecharacteris leftuntouched. CharactersmappedtoNonearedeleted.upper(self,/) Returnacopyofthestringconvertedtouppercase.zfill(self,width,/)  adanumericstringwithzerosontheleft,tofillafieldofthegivenwidth. Thestringisnevertruncated.目录字符串驻留机制工作原理显式驻留字符串长短的分界附:字符串方法完
|
|