国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Jadual Kandungan
1 Unicode
2 Unicode dalam Python
2.1 Faedah objek Unicode
2.2 Pengoptimuman Python bagi Unicode
3 Unicode對象的底層結(jié)構(gòu)體
3.1 PyASCIIObject
3.2 PyCompactUnicodeObject
3.3 PyUnicodeObject
3.4 示例
4 interned機制
Rumah pembangunan bahagian belakang Tutorial Python Analisis kod sumber str jenis terbina dalam Python

Analisis kod sumber str jenis terbina dalam Python

May 09, 2023 pm 02:16 PM
python str

1 Unicode

Unit asas storan komputer ialah bait, yang terdiri daripada 8 bit. Memandangkan bahasa Inggeris hanya terdiri daripada 26 huruf ditambah beberapa simbol, aksara Inggeris boleh disimpan terus dalam bait. Tetapi bahasa lain (seperti Cina, Jepun, Korea, dll.) perlu menggunakan berbilang bait untuk pengekodan kerana bilangan aksara yang banyak.

Dengan penyebaran teknologi komputer, teknologi pengekodan aksara bukan Latin terus berkembang, tetapi masih terdapat dua batasan utama:

  • Tidak menyokong berbilang bahasa: skema pengekodan satu bahasa tidak boleh digunakan untuk bahasa lain

  • Tiada standard bersatu: contohnya, bahasa Cina mempunyai GBK, GB2312, GB18030 dan piawaian pengekodan lain

Oleh kerana kaedah pengekodan tidak seragam, pembangun perlu menukar berulang-alik antara pengekodan yang berbeza, dan banyak ralat pasti akan berlaku. Untuk menyelesaikan masalah ketidakkonsistenan seperti ini, standard Unicode telah dicadangkan. Unicode mengatur dan mengekod kebanyakan sistem penulisan di dunia, membolehkan komputer memproses teks dengan cara yang bersatu. Unicode kini mengandungi lebih daripada 140,000 aksara dan secara semula jadi menyokong berbilang bahasa. (Uni Unicode ialah punca “penyatuan”)

2 Unicode dalam Python

2.1 Faedah objek Unicode

Selepas Python 3, Unicode digunakan secara dalaman dalam objek str Mewakili, dan oleh itu menjadi objek Unicode dalam kod sumber. Kelebihan menggunakan perwakilan Unicode ialah logik teras program menggunakan Unicode secara seragam, dan hanya perlu dinyahkod dan dikodkan pada lapisan input dan output, yang boleh mengelakkan pelbagai masalah pengekodan setakat yang paling besar.

Rajah adalah seperti berikut:

Analisis kod sumber str jenis terbina dalam Python

2.2 Pengoptimuman Python bagi Unicode

Masalah: Memandangkan Unicode mengandungi lebih daripada 140,000 aksara, setiap A aksara memerlukan sekurang-kurangnya 4 bait untuk disimpan (ini mungkin kerana 2 bait tidak mencukupi, jadi 4 bait digunakan dan 3 bait biasanya tidak digunakan). Kod ASCII untuk aksara Inggeris memerlukan hanya 1 bait Penggunaan Unicode akan menggandakan kos aksara Inggeris yang kerap digunakan.

Pertama, mari kita lihat perbezaan saiz pelbagai bentuk objek str dalam Python:

>>> sys.getsizeof('ab') - sys.getsizeof('a')
1
>>> sys.getsizeof('一二') - sys.getsizeof('一')
2
>>> sys.getsizeof('????????') - sys.getsizeof('????')
4

Dapat dilihat bahawa Python secara dalaman mengoptimumkan objek Unicode: mengikut kandungan teks, unit storan asas dipilih.

Storan asas objek Unicode dibahagikan kepada tiga kategori mengikut julat titik kod Unikod aksara teks:

  • PyUnicode_1BYTE_KIND: Semua titik kod aksara berada di antara U+ 0000 dan U+00FF

  • PyUnicode_2BYTE_KIND: Semua titik kod aksara adalah antara U+0000 dan U+FFFF, dan sekurang-kurangnya satu aksara mempunyai titik kod lebih besar daripada U+00FF

  • PyUnicode_1BYTE_KIND: Semua titik kod aksara adalah antara U+0000 dan U+10FFFF, dan sekurang-kurangnya satu aksara mempunyai titik kod lebih besar daripada U+FFFF

Penghitungan yang sepadan adalah seperti berikut:

enum PyUnicode_Kind {
/* String contains only wstr byte characters.  This is only possible
   when the string was created with a legacy API and _PyUnicode_Ready()
   has not been called yet.  */
    PyUnicode_WCHAR_KIND = 0,
/* Return values of the PyUnicode_KIND() macro: */
    PyUnicode_1BYTE_KIND = 1,
    PyUnicode_2BYTE_KIND = 2,
    PyUnicode_4BYTE_KIND = 4
};

Pilih unit storan yang berbeza mengikut klasifikasi yang berbeza:

/* Py_UCS4 and Py_UCS2 are typedefs for the respective
   unicode representations. */
typedef uint32_t Py_UCS4;
typedef uint16_t Py_UCS2;
typedef uint8_t Py_UCS1;

Hubungan yang sepadan adalah seperti berikut:

文本類型字符存儲單元字符存儲單元大小(字節(jié))
PyUnicode_1BYTE_KINDPy_UCS11
PyUnicode_2BYTE_KINDPy_UCS22
PyUnicode_4BYTE_KINDPy_UCS44

Sejak Unicode struktur storan dalaman berbeza-beza bergantung pada jenis teks, jenis jenis mesti disimpan sebagai medan awam objek Unicode. Python secara dalaman mentakrifkan beberapa bit bendera sebagai medan awam Unicode: (Disebabkan tahap pengarang yang terhad, semua medan di sini tidak akan diperkenalkan dalam kandungan seterusnya. Anda boleh mempelajarinya sendiri kemudian. Pegang penumbuk anda~)

  • dibawa masuk: Sama ada hendak mengekalkan mekanisme yang diinternet

  • jenis: jenis, digunakan untuk membezakan saiz unit storan asas bagi aksara

  • padat: kaedah peruntukan memori, sama ada objek dan penimbal teks dipisahkan

  • asscii: sama ada teks semuanya ASCII tulen

melalui fungsi PyUnicode_New, mengikut bilangan saiz aksara teks dan maxchar aksara maksimum memulakan objek Unicode. Fungsi ini terutamanya memilih unit storan aksara yang paling padat dan struktur asas untuk objek Unicode berdasarkan maxchar: (Kod sumber agak panjang, jadi ia tidak akan disenaraikan di sini. Anda boleh memahaminya sendiri. Ia ditunjukkan dalam bentuk jadual di bawah )

maxchar < 128128 <= maxchar < 256256 <= maxchar < 6553665536 <= maxchar < MAX_UNICODE
kindPyUnicode_1BYTE_KINDPyUnicode_1BYTE_KINDPyUnicode_2BYTE_KINDPyUnicode_4BYTE_KIND
ascii1000
字符存儲單元大?。ㄗ止?jié))1124
底層結(jié)構(gòu)體PyASCIIObjectPyCompactUnicodeObjectPyCompactUnicodeObjectPyCompactUnicodeObject

3 Unicode對象的底層結(jié)構(gòu)體

3.1 PyASCIIObject

C源碼:

typedef struct {
    PyObject_HEAD
    Py_ssize_t length;          /* Number of code points in the string */
    Py_hash_t hash;             /* Hash value; -1 if not set */
    struct {
        unsigned int interned:2;
        unsigned int kind:3;
        unsigned int compact:1;
        unsigned int ascii:1;
        unsigned int ready:1;
        unsigned int :24;
    } state;
    wchar_t *wstr;              /* wchar_t representation (null-terminated) */
} PyASCIIObject;

源碼分析:

length:文本長度

hash:文本哈希值

state:Unicode對象標(biāo)志位

wstr:緩存C字符串的一個wchar_t指針,以“\0”結(jié)束(這里和我看的另一篇文章講得不太一樣,另一個描述是:ASCII文本緊接著位于PyASCIIObject結(jié)構(gòu)體后面,我個人覺得現(xiàn)在的這種說法比較準確,畢竟源碼結(jié)構(gòu)體后面沒有別的字段了)

圖示如下:

(注意這里state字段后面有一個4字節(jié)大小的空洞,這是結(jié)構(gòu)體字段內(nèi)存對齊造成的現(xiàn)象,主要是為了優(yōu)化內(nèi)存訪問效率)

Analisis kod sumber str jenis terbina dalam Python

ASCII文本由wstr指向,以’abc’和空字符串對象’'為例:

Analisis kod sumber str jenis terbina dalam Python

Analisis kod sumber str jenis terbina dalam Python

3.2 PyCompactUnicodeObject

如果文本不全是ASCII,Unicode對象底層便由PyCompactUnicodeObject結(jié)構(gòu)體保存。C源碼如下:

/* Non-ASCII strings allocated through PyUnicode_New use the
   PyCompactUnicodeObject structure. state.compact is set, and the data
   immediately follow the structure. */
typedef struct {
    PyASCIIObject _base;
    Py_ssize_t utf8_length;     /* Number of bytes in utf8, excluding the
                                 * terminating \0. */
    char *utf8;                 /* UTF-8 representation (null-terminated) */
    Py_ssize_t wstr_length;     /* Number of code points in wstr, possible
                                 * surrogates count as two code points. */
} PyCompactUnicodeObject;

PyCompactUnicodeObject在PyASCIIObject的基礎(chǔ)上增加了3個字段:

utf8_length:文本UTF8編碼長度

utf8:文本UTF8編碼形式,緩存以避免重復(fù)編碼運算

wstr_length:wstr的“長度”(這里所謂的長度沒有找到很準確的說法,筆者也不太清楚怎么能打印出來,大家可以自行研究下)

注意到,PyASCIIObject中并沒有保存UTF8編碼形式,這是因為ASCII本身就是合法的UTF8,這也是ASCII文本底層由PyASCIIObject保存的原因。

結(jié)構(gòu)圖示:

Analisis kod sumber str jenis terbina dalam Python

3.3 PyUnicodeObject

PyUnicodeObject則是Python中str對象的具體實現(xiàn)。C源碼如下:

/* Strings allocated through PyUnicode_FromUnicode(NULL, len) use the
   PyUnicodeObject structure. The actual string data is initially in the wstr
   block, and copied into the data block using _PyUnicode_Ready. */
typedef struct {
    PyCompactUnicodeObject _base;
    union {
        void *any;
        Py_UCS1 *latin1;
        Py_UCS2 *ucs2;
        Py_UCS4 *ucs4;
    } data;                     /* Canonical, smallest-form Unicode buffer */
} PyUnicodeObject;

3.4 示例

在日常開發(fā)時,要結(jié)合實際情況注意字符串拼接前后的內(nèi)存大小差別:

>>> import sys
>>> text = &#39;a&#39; * 1000
>>> sys.getsizeof(text)
1049
>>> text += &#39;????&#39;
>>> sys.getsizeof(text)
4080

4 interned機制

如果str對象的interned標(biāo)志位為1,Python虛擬機將為其開啟interned機制,

源碼如下:(相關(guān)信息在網(wǎng)上可以看到很多說法和解釋,這里筆者能力有限,暫時沒有找到最確切的答案,之后補充。抱拳~但是我們通過分析源碼應(yīng)該是能看出一些門道的)

/* This dictionary holds all interned unicode strings.  Note that references
   to strings in this dictionary are *not* counted in the string&#39;s ob_refcnt.
   When the interned string reaches a refcnt of 0 the string deallocation
   function will delete the reference from this dictionary.
   Another way to look at this is that to say that the actual reference
   count of a string is:  s->ob_refcnt + (s->state ? 2 : 0)
*/
static PyObject *interned = NULL;
void
PyUnicode_InternInPlace(PyObject **p)
{
    PyObject *s = *p;
    PyObject *t;
#ifdef Py_DEBUG
    assert(s != NULL);
    assert(_PyUnicode_CHECK(s));
#else
    if (s == NULL || !PyUnicode_Check(s))
        return;
#endif
    /* If it&#39;s a subclass, we don&#39;t really know what putting
       it in the interned dict might do. */
    if (!PyUnicode_CheckExact(s))
        return;
    if (PyUnicode_CHECK_INTERNED(s))
        return;
    if (interned == NULL) {
        interned = PyDict_New();
        if (interned == NULL) {
            PyErr_Clear(); /* Don&#39;t leave an exception */
            return;
        }
    }
    Py_ALLOW_RECURSION
    t = PyDict_SetDefault(interned, s, s);
    Py_END_ALLOW_RECURSION
    if (t == NULL) {
        PyErr_Clear();
        return;
    }
    if (t != s) {
        Py_INCREF(t);
        Py_SETREF(*p, t);
        return;
    }
    /* The two references in interned are not counted by refcnt.
       The deallocator will take care of this */
    Py_REFCNT(s) -= 2;
    _PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL;
}

可以看到,源碼前面還是做一些基本的檢查。我們可以看一下37行和50行:將s添加到interned字典中時,其實s同時是key和value(這里我不太清楚為什么會這樣做),所以s對應(yīng)的引用計數(shù)是+2了的(具體可以看PyDict_SetDefault()的源碼),所以在50行時會將計數(shù)-2,保證引用計數(shù)的正確。

考慮下面的場景:

>>> class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age
>>> user = User(&#39;Tom&#39;, 21)
>>> user.__dict__
{&#39;name&#39;: &#39;Tom&#39;, &#39;age&#39;: 21}

由于對象的屬性由dict保存,這意味著每個User對象都要保存一個str對象‘name’,這會浪費大量的內(nèi)存。而str是不可變對象,因此Python內(nèi)部將有潛在重復(fù)可能的字符串都做成單例模式,這就是interned機制。Python具體做法就是在內(nèi)部維護一個全局dict對象,所有開啟interned機制的str對象均保存在這里,后續(xù)需要使用的時候,先創(chuàng)建,如果判斷已經(jīng)維護了相同的字符串,就會將新創(chuàng)建的這個對象回收掉。

示例:

由不同運算生成’abc’,最后都是同一個對象:

>>> a = &#39;abc&#39;
>>> b = &#39;ab&#39; + &#39;c&#39;
>>> id(a), id(b), a is b
(2752416949872, 2752416949872, True)

Atas ialah kandungan terperinci Analisis kod sumber str jenis terbina dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Cara Mengendalikan Pengesahan API di Python Cara Mengendalikan Pengesahan API di Python Jul 13, 2025 am 02:22 AM

Kunci untuk menangani pengesahan API adalah untuk memahami dan menggunakan kaedah pengesahan dengan betul. 1. Apikey adalah kaedah pengesahan yang paling mudah, biasanya diletakkan dalam tajuk permintaan atau parameter URL; 2. BasicAuth menggunakan nama pengguna dan kata laluan untuk penghantaran pengekodan Base64, yang sesuai untuk sistem dalaman; 3. OAuth2 perlu mendapatkan token terlebih dahulu melalui client_id dan client_secret, dan kemudian bawa bearertoken dalam header permintaan; 4. Untuk menangani tamat tempoh token, kelas pengurusan token boleh dikemas dan secara automatik menyegarkan token; Singkatnya, memilih kaedah yang sesuai mengikut dokumen dan menyimpan maklumat utama adalah kunci.

Cara Menguji API dengan Python Cara Menguji API dengan Python Jul 12, 2025 am 02:47 AM

Untuk menguji API, anda perlu menggunakan Perpustakaan Permintaan Python. Langkah -langkahnya adalah untuk memasang perpustakaan, menghantar permintaan, mengesahkan respons, menetapkan masa dan cuba semula. Pertama, pasang perpustakaan melalui PipinstallRequests; kemudian gunakan permintaan.get () atau requests.post () dan kaedah lain untuk menghantar permintaan GET atau pos; Kemudian semak respons.status_code dan response.json () untuk memastikan hasil pulangan mematuhi jangkaan; Akhirnya, tambah parameter tamat masa untuk menetapkan masa tamat, dan menggabungkan perpustakaan semula untuk mencapai percubaan automatik untuk meningkatkan kestabilan.

Skop pembolehubah python dalam fungsi Skop pembolehubah python dalam fungsi Jul 12, 2025 am 02:49 AM

Dalam Python, pembolehubah yang ditakrifkan di dalam fungsi adalah pembolehubah tempatan dan hanya sah dalam fungsi; Ditakrifkan secara luaran adalah pembolehubah global yang boleh dibaca di mana sahaja. 1. Pembolehubah tempatan dimusnahkan kerana fungsi dilaksanakan; 2. Fungsi ini boleh mengakses pembolehubah global tetapi tidak dapat diubahsuai secara langsung, jadi kata kunci global diperlukan; 3. Jika anda ingin mengubah suai pembolehubah fungsi luar dalam fungsi bersarang, anda perlu menggunakan kata kunci nonlocal; 4. Pembolehubah dengan nama yang sama tidak mempengaruhi satu sama lain dalam skop yang berbeza; 5. Global mesti diisytiharkan apabila mengubah suai pembolehubah global, jika tidak, kesilapan unboundlocalerror akan dibangkitkan. Memahami peraturan ini membantu mengelakkan pepijat dan menulis lebih banyak fungsi yang boleh dipercayai.

Tutorial Python Fastapi Tutorial Python Fastapi Jul 12, 2025 am 02:42 AM

Untuk mewujudkan API moden dan cekap menggunakan Python, FastAPI disyorkan; Ia berdasarkan kepada jenis python standard yang diminta dan secara automatik dapat menghasilkan dokumen, dengan prestasi yang sangat baik. Selepas memasang FastAPI dan Asgi Server UVicorn, anda boleh menulis kod antara muka. Dengan menentukan laluan, menulis fungsi pemprosesan, dan data yang kembali, API boleh dibina dengan cepat. FastAPI menyokong pelbagai kaedah HTTP dan menyediakan sistem dokumentasi Swaggersui dan Redoc yang dihasilkan secara automatik. Parameter URL boleh ditangkap melalui definisi laluan, manakala parameter pertanyaan boleh dilaksanakan dengan menetapkan nilai lalai untuk parameter fungsi. Penggunaan rasional model Pydantic dapat membantu meningkatkan kecekapan dan ketepatan pembangunan.

Python untuk gelung dengan tamat masa Python untuk gelung dengan tamat masa Jul 12, 2025 am 02:17 AM

Tambah kawalan tamat masa ke Python untuk gelung. 1. Anda boleh merakam masa mula dengan modul masa, dan menilai sama ada ia ditetapkan dalam setiap lelaran dan menggunakan rehat untuk melompat keluar dari gelung; 2. Untuk mengundi tugas kelas, anda boleh menggunakan gelung sementara untuk memadankan penghakiman masa, dan menambah tidur untuk mengelakkan kepenuhan CPU; 3. Kaedah lanjutan boleh mempertimbangkan threading atau isyarat untuk mencapai kawalan yang lebih tepat, tetapi kerumitannya tinggi, dan tidak disyorkan untuk pemula memilih; Ringkasan Mata Utama: Penghakiman masa manual adalah penyelesaian asas, sementara lebih sesuai untuk tugas kelas menunggu masa yang terhad, tidur sangat diperlukan, dan kaedah lanjutan sesuai untuk senario tertentu.

Bagaimana cara menghuraikan fail JSON yang besar di Python? Bagaimana cara menghuraikan fail JSON yang besar di Python? Jul 13, 2025 am 01:46 AM

Bagaimana cara mengendalikan fail JSON yang besar di Python? 1. Gunakan Perpustakaan IJSON untuk mengalir dan mengelakkan limpahan memori melalui parsing item demi item; 2. Jika dalam format Jsonlines, anda boleh membacanya dengan garis dan memprosesnya dengan json.loads (); 3. Atau memecah fail besar ke dalam kepingan kecil dan kemudian memprosesnya secara berasingan. Kaedah ini dengan berkesan menyelesaikan masalah batasan memori dan sesuai untuk senario yang berbeza.

Python untuk gelung di atas tuple Python untuk gelung di atas tuple Jul 13, 2025 am 02:55 AM

Di Python, kaedah melintasi tupel dengan gelung termasuk secara langsung melelehkan unsur -unsur, mendapatkan indeks dan elemen pada masa yang sama, dan memproses tuple bersarang. 1. Gunakan gelung untuk terus mengakses setiap elemen dalam urutan tanpa menguruskan indeks; 2. Gunakan penghitungan () untuk mendapatkan indeks dan nilai pada masa yang sama. Indeks lalai adalah 0, dan parameter permulaan juga boleh ditentukan; 3. Di samping itu, tuple tidak berubah dan kandungan tidak dapat diubah suai dalam gelung. Nilai yang tidak diingini boleh diabaikan oleh \ _. Adalah disyorkan untuk memeriksa sama ada tuple kosong sebelum melintasi untuk mengelakkan kesilapan.

Apakah argumen lalai Python dan isu potensi mereka? Apakah argumen lalai Python dan isu potensi mereka? Jul 12, 2025 am 02:39 AM

Parameter lalai Python dinilai dan nilai tetap apabila fungsi ditakrifkan, yang boleh menyebabkan masalah yang tidak dijangka. Menggunakan objek berubah -ubah seperti senarai sebagai parameter lalai akan mengekalkan pengubahsuaian, dan disyorkan untuk menggunakan tiada sebaliknya; Skop parameter lalai adalah pembolehubah persekitaran apabila ditakrifkan, dan perubahan pembolehubah berikutnya tidak akan menjejaskan nilai mereka; Elakkan bergantung pada parameter lalai untuk menyelamatkan keadaan, dan keadaan enkapsulasi kelas harus digunakan untuk memastikan konsistensi fungsi.

See all articles