找回密码
 会员注册
查看: 25|回复: 0

python字符串驻留机制

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-7 13:18:59 | 显示全部楼层 |阅读模式
偶然发现一个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.目录字符串驻留机制工作原理显式驻留字符串长短的分界附:字符串方法完
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 22:59 , Processed in 0.799078 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表