Rumah  >  Soal Jawab  >  teks badan

Python newbie, saya ingin bertanya soalan tentang lapisan bawah jenis pembolehubah dan jenis tidak berubah.

Kod pertama:

a = "hello"   #定义一个字符串的变量
print(id(a))  #第一次的地址
print(a)      #a = hello
a = a.upper() # 单纯的a.upper() 执行过后,无法存储到a本身,必须得重新赋值给a  换句话说,a在被upper之后,重新指向了一个新的地址
print(id(a))  #第二次的地址
print(a)

Hasil pelaksanaan kod pertama:

Kod kedua:

b = [11,22,33,44,55]  #定义一个列表的变量
print(id(b))          #第一次的地址
print(b)              #b = [11,22,33,44,55]
b.append(99)          #单纯的b.append()执行过后,不需要存储到b,因为b已经被更改
print(id(b))          #检查第一次的地址
print(b)              #发现在第一次地址当中,b已经改变
#b = b.append(99)     #如果将修改b这个行为赋值到b
#print(id(b))         #检查地址,发现已经变更
#print(b)             #检查b的值,发现已经变更。b的值为none   因为b.append(99)本身的返回值为none
#[***列表为可修改变量,因此修改完之后,地址跟原来的一样。反而是如果像修改字符串那样重新赋值,变得不可行。原因在于append语句本身并不返回值。***]
#字符串赋值之后放在内存一个地址,这个地址上面的字符串是无法更改的,只能重新做一个新的字符串,然后改变变量的指向位置。
#而列表赋值之后存在一个内存的地址,这个列表里面的值是可以直接修改的。不需要重新做一个新的列表,然后改变变量的指向位置。

Hasil pelaksanaan kod kedua:

Dalam proses pembelajaran ular sawa, saya diberitahu bahawa rentetan adalah jenis tidak berubah dan senarai adalah jenis boleh ubah. Dalam erti kata lain, jika saya ingin menukar rentetan, saya sebenarnya mencipta rentetan baru dan meletakkannya di alamat baharu memori Rentetan asal masih sama. Seperti yang ditunjukkan dalam sekeping kod pertama.
Senarai berbeza, senarai boleh diubah suai terus pada alamat memori asal. Seperti yang ditunjukkan dalam sekeping kod kedua.
Soalan saya:
Apakah perbezaan asas antara jenis boleh ubah dan jenis tidak berubah? Mengapa perbezaan ini berlaku? Kenapa dalam kod pertama, jika a ingin menukar, alamat mesti ditukar, tetapi dalam kod kedua, b boleh terus mengubah suai nilai senarai tanpa menukar alamat. Apakah logik asas di sini? Saya tertanya-tanya adakah ia bermakna bahawa senarai itu sendiri sebenarnya adalah koleksi nilai Ia hanya mencerminkan koleksi itu sendiri dan menunjukkan koleksi nilai ke tempat ini, jadi ia boleh diubah suai. Saya tidak tahu sama ada saya menyatakannya dengan jelas.
Saya sangat ingin tahu tentang perkara ini, maksudnya, apakah sebenarnya senarai itu? Rentetan tidak boleh ditukar. Selepas pergi lebih dalam ke bawah, apakah mereka berdua?

给我你的怀抱给我你的怀抱2658 hari yang lalu667

membalas semua(4)saya akan balas

  • 大家讲道理

    大家讲道理2017-06-12 09:23:12

    Malah, objek boleh berubah dan tidak berubah, yapy, 都是内部实现的问题, 如果我修改相应的方法, 将其写回到本身, 这样也能模仿出可变的现象, 就小小类似tuplelist的关系,
    既然想了解底层, 那就直接看源码吧:
    这是字符串的upper()

    static PyObject *
    string_upper(PyStringObject *self)
    {
        char *s;
        Py_ssize_t i, n = PyString_GET_SIZE(self); # 取出字符串对象中字符串的长度
        PyObject *newobj;
    
        newobj = PyString_FromStringAndSize(NULL, n); # 可以理解成申请内存空间
        if (!newobj)
            return NULL;
    
        s = PyString_AS_STRING(newobj);  # 从newobj对象取出具体字符串指针
    
        Py_MEMCPY(s, PyString_AS_STRING(self), n); # 拷贝旧的字符串
    
        for (i = 0; i < n; i++) {
            int c = Py_CHARMASK(s[i]);
            if (islower(c))
                s[i] = _toupper(c);   # 修改对应指针位置上的内容
        }
    
        return newobj;  # 返回新字符串对象 (区分字符串对象和里面字符串的指针)
    }
    

    Ini senarainyaappend

    int
    PyList_Append(PyObject *op, PyObject *newitem)
    {
        if (PyList_Check(op) && (newitem != NULL))
            return app1((PyListObject *)op, newitem);
        PyErr_BadInternalCall();
        return -1;
    }
    
    static int
    app1(PyListObject *self, PyObject *v)
    {
        Py_ssize_t n = PyList_GET_SIZE(self);
    
        assert (v != NULL);
        if (n == PY_SSIZE_T_MAX) {
            PyErr_SetString(PyExc_OverflowError,
                "cannot add more objects to list");
            return -1;
        }
    
        if (list_resize(self, n+1) == -1)
            return -1;
    
        Py_INCREF(v);
        PyList_SET_ITEM(self, n, v);   # 因为列表是头和和成员分开的, 所以直接将新成员追加在原来的成员数组后面, 长度变化通过resize实现
        return 0;
    }

    balas
    0
  • 巴扎黑

    巴扎黑2017-06-12 09:23:12

    Rentetan Python dicache Jika dua rentetan yang sama berada dalam pembolehubah a dan b yang berbeza, id(a) dan id(b) mereka adalah sama.
    Tetapi jika rujukan a dan b ialah 0, objek akan dimusnahkan secara automatik.

    Contoh poster asal:

    a = a.atas()

    Kandungan pembolehubah a telah berubah dan berbeza Kandungan lama tidak mempunyai rujukan dan objek dimusnahkan oleh kutipan sampah.
    b ialah senarai, ia berubah-ubah, dan anda boleh memohon memori sekali lagi. Pada masa yang sama, b mempunyai rujukan kandungan dan tidak akan dimusnahkan.

    balas
    0
  • 为情所困

    为情所困2017-06-12 09:23:12

    Pergi lebih dalam dan lihat kod sumber C python~

    Ia boleh menjadi tidak berubah, yang ditetapkan oleh bahasa python.

    Jenis tidak berubah tidak menyediakan kaedah untuk mengubah suai objek itu sendiri, manakala jenis boleh ubah menyediakan kaedah ini. Tidak ada yang misteri tentang perbezaan ini.

    balas
    0
  • 仅有的幸福

    仅有的幸福2017-06-12 09:23:12

    Dari perspektif perkakasan, antara muka yang diberikan kepada pengguna ditetapkan mengikut peraturan, dan memori dikendalikan dengan cara yang tetap. Tiada kebolehubah atau kebolehubah.
    Naik ialah lapisan sistem pengendalian, yang merangkumi sejumlah besar API perkakasan untuk memperkayakan operasi pengguna. Jurubahasa Python ditulis dalam bahasa C Apabila menggunakan Python, hanya pragmatik Python yang digunakan untuk menulis kod penterjemah untuk pelaksanaan Di bawah premis di atas, untuk menjelaskan masalah semasa, kebolehubahan dan kebolehubahan Python ditetapkan oleh pencipta Python Cara untuk melaksanakan peraturan ini mungkin dengan memanggil API asas yang berbeza, atau API asas yang berbeza. dilaksanakan dengan menggabungkan antara satu sama lain. Peruntukan ini disediakan kepada pengguna dalam bentuk pragmatik Python, dan akhirnya disusun menjadi 0,1 untuk pelaksanaan komputer. Bagi pengguna, objek boleh ubah dan tidak boleh diubah ialah ciri yang disediakan oleh bahasa dan boleh melengkapkan beberapa fungsi, tetapi sebenarnya tiada perbezaan untuk komputer.

    balas
    0
  • Batalbalas