Utas ini membahas cara mendapatkan nama fungsi sebagai string dengan Python: Bagaimana cara mendapatkan nama fungsi sebagai string?
Bagaimana saya bisa melakukan hal yang sama untuk suatu variabel? Berbeda dengan fungsi, variabel Python tidak memiliki __name__
atribut.
Dengan kata lain, jika saya memiliki variabel seperti:
foo = dict()
foo['bar'] = 2
Saya mencari fungsi / atribut, misalnya retrieve_name()
untuk membuat DataFrame di Panda dari daftar ini , di mana nama kolom diberikan oleh nama-nama kamus aktual:
# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [retrieve_name(d) for d in list_of_dicts]
pip3 install python-varname==0.1.5
; diimpor menggunakanfrom varname import nameof
test = {}
print(varname.nameof(test))
for i in [0]:
print(varname.nameof(test))
Cetakan pertama memberitest
, cetakan dalam lingkaran itu memunculkanVarnameRetrievingError: Callee's node cannot be detected.
v0.2.0
Satu-satunya objek dalam Python yang memiliki nama kanonik adalah modul, fungsi, dan kelas, dan tentu saja tidak ada jaminan bahwa nama kanonik ini memiliki arti dalam ruang nama apa pun setelah fungsi atau kelas didefinisikan atau modul diimpor. Nama-nama ini juga dapat dimodifikasi setelah objek dibuat sehingga mereka tidak selalu dapat dipercaya.
Apa yang ingin Anda lakukan tidak mungkin tanpa secara rekursif berjalan di pohon objek bernama ; nama adalah referensi satu arah ke suatu objek. Objek Python umum atau variasi taman tidak berisi referensi untuk namanya. Bayangkan jika setiap bilangan bulat, setiap dict, setiap daftar, setiap Boolean perlu mempertahankan daftar string yang mewakili nama yang merujuknya! Ini akan menjadi mimpi buruk implementasi, dengan sedikit manfaat bagi programmer.
sumber
__name__
selalu dapat dimodifikasi, yang berarti bahwa nama "kanonik" mungkin bukan nama yang dapat digunakan untuk mendapatkan objek (misalnya saat membuat kelas secara dinamis).Bahkan jika nilai variabel tidak menunjuk kembali ke nama, Anda memiliki akses ke daftar setiap variabel yang ditugaskan dan nilainya, jadi saya kagum bahwa hanya satu orang yang menyarankan perulangan di sana untuk mencari nama var Anda.
Seseorang yang disebutkan pada jawaban itu bahwa Anda mungkin harus berjalan tumpukan dan memeriksa semua orang lokal dan global untuk menemukan
foo
, tetapi jikafoo
ditugaskan dalam lingkup di mana Anda memanggilretrieve_name
fungsi ini , Anda dapat menggunakaninspect
itucurrent frame
untuk membuat Anda semua variabel-variabel lokal .Penjelasan saya mungkin agak terlalu bertele-tele (mungkin saya seharusnya menggunakan kata "foo" lebih sedikit), tapi di sini caranya akan terlihat dalam kode ( Perhatikan bahwa jika ada lebih dari satu variabel yang ditugaskan ke nilai yang sama, Anda akan dapatkan kedua nama variabel tersebut ):
Jika Anda memanggil fungsi ini dari fungsi lain, sesuatu seperti:
Dan Anda menginginkan,
baz
alih - alihbar
, Anda hanya perlu kembali lingkup lebih jauh. Ini dapat dilakukan dengan menambahkan ekstra.f_back
dalamcaller_local_vars
inisialisasi.Lihat contoh di sini: ideone
sumber
import hooks
,ironpython
, danjython
a, b = 2, 2
,retrieve_name(a)
danretrieve_name(b)
keduanya akan kembali['a', 'b']
atau['b', 'a']
true
untukis
perbandingandef foo(bar): retrieve_name(bar)
akan selalu mengembalikan bar, tetapi bagaimana jika Anda inginfoo(baz)
kembalibaz
) bukanbar
?callers_local_vars
untuk pergi satu lingkup lebih jauh ke belakang sehingga akan melihat lingkup apa pun yang memanggilfoo
. Ubah baris menjadiinspect.currentframe().f_back.f_back.f_locals.items()
(perhatikan tambahanf_back
).Dengan Python 3.8 orang cukup menggunakan fitur debugging f-string:
sumber
f'{foo=}'.split('=')[0].split('.')[-1]
Pada python3, fungsi ini akan mendapatkan nama paling luar di stack:
Ini berguna di mana saja pada kode. Melintasi tumpukan yang terbalik mencari pertandingan pertama.
sumber
retrieve_name(SomeClass.some_attribute)
tidak berhasil. Bisakah Anda membantu lebih jauh tentang itu?stop_on_error
Saya tidak percaya ini mungkin. Perhatikan contoh berikut:
Titik
a
danb
ke objek yang sama, tetapi objek tidak dapat mengetahui variabel apa yang mengarah ke sana.sumber
Ini digunakan seperti ini:
sumber
name(variable=variable)
akan menampilkan['variable']
, dan menggunakan tidakname(variable=another_variable)
akan menghasilkan melainkan .['another_variable']
['variable']
>>> a = []
>>> b = a
>>> name(a=b)
['a']
>>> name(b=a)
['b']
`Inilah satu pendekatan. Saya tidak akan merekomendasikan ini untuk hal yang penting, karena itu akan sangat rapuh. Tapi itu bisa dilakukan.
Buat fungsi yang menggunakan
inspect
modul untuk menemukan kode sumber yang memanggilnya. Kemudian Anda dapat mengurai kode sumber untuk mengidentifikasi nama variabel yang ingin Anda ambil. Misalnya, inilah fungsi yang dipanggilautodict
yang mengambil daftar variabel dan mengembalikan kamus nama variabel pemetaan ke nilai-nilai mereka. Misalnya:Akan memberi:
Memeriksa kode sumber itu sendiri lebih baik daripada mencari melalui
locals()
atauglobals()
karena pendekatan yang terakhir tidak memberi tahu Anda mana dari variabel yang Anda inginkan.Bagaimanapun, inilah kodenya:
Tindakan terjadi di baris dengan
inspect.getouterframes
, yang mengembalikan string dalam kode yang dipanggilautodict
.Kelemahan yang jelas untuk jenis sihir ini adalah bahwa ia membuat asumsi tentang bagaimana kode sumber terstruktur. Dan tentu saja, itu tidak akan berfungsi sama sekali jika dijalankan di dalam interpreter.
sumber
Saya menulis paket sihir untuk melakukan sihir semacam ini dengan kuat. Kamu bisa menulis:
dan meneruskannya ke konstruktor dataframe. Ini setara dengan:
sumber
Jika Anda ingin menulis fungsi Anda sendiri, bisa dilakukan sedemikian rupa sehingga Anda bisa memeriksa variabel yang ditentukan dalam lokal kemudian memeriksa global. Jika tidak ada yang ditemukan, Anda dapat membandingkan pada id () untuk melihat apakah variabel menunjuk ke lokasi yang sama dalam memori.
Jika variabel Anda ada di kelas, Anda bisa menggunakan className. dict .keys () atau vars (self) untuk melihat apakah variabel Anda telah didefinisikan.
sumber
locals
danglobals
... dan Anda berisiko salah nama jika tidak ada yang benar-benar ada. Ini adalah satu ton pekerjaan tanpa hasil yang bermanfaat.Dalam Python,
def
danclass
kata kunci akan mengikat nama tertentu ke objek yang mereka tetapkan (fungsi atau kelas). Demikian pula, modul diberi nama berdasarkan disebut sesuatu yang spesifik dalam sistem file. Dalam ketiga kasus, ada cara yang jelas untuk menetapkan nama "kanonik" ke objek yang dimaksud.Namun, untuk jenis objek lainnya, nama kanonik semacam itu mungkin tidak ada . Misalnya, perhatikan elemen daftar. Elemen-elemen dalam daftar tidak disebutkan secara individual, dan sangat mungkin bahwa satu-satunya cara untuk merujuk mereka dalam suatu program adalah dengan menggunakan indeks daftar pada daftar yang berisi. Jika daftar objek seperti itu diteruskan ke fungsi Anda, Anda tidak mungkin dapat menetapkan pengidentifikasi yang berarti untuk nilai.
Python tidak menyimpan nama di sisi kiri penugasan ke objek yang ditugaskan karena:
Jadi, misalnya, fungsi yang didefinisikan menggunakan
lambda
akan selalu memiliki "nama"<lambda>
, bukan nama fungsi tertentu.Pendekatan terbaik adalah dengan meminta pemanggil untuk memberikan daftar nama (opsional). Jika mengetik
'...','...'
terlalu rumit, Anda bisa menerima mis. String tunggal yang berisi daftar nama yang dipisahkan koma (sepertinamedtuple
halnya).sumber
lokal () - Mengembalikan kamus yang berisi variabel lokal lingkup saat ini. dengan mengulangi kamus ini kita dapat memeriksa kunci yang memiliki nilai sama dengan variabel yang didefinisikan, hanya mengekstrak kunci akan memberi kita teks variabel dalam format string.
dari (setelah sedikit perubahan) https://www.tutorialspoint.com/How-to-get-a-variable-name-as-a-string-in-Python
sumber
Saya pikir sangat sulit untuk melakukan ini dengan Python karena fakta sederhana bahwa Anda tidak akan pernah tahu nama variabel yang Anda gunakan. Jadi, dalam contohnya, Anda dapat melakukan:
Dari pada:
sumber
hanyalah cara lain untuk melakukan ini berdasarkan konten dari variabel input:
(mengembalikan nama variabel pertama yang cocok dengan variabel input, jika tidak Tidak ada. Seseorang dapat memodifikasinya untuk mendapatkan semua nama variabel yang memiliki konten yang sama dengan variabel input)
sumber
Fungsi ini akan mencetak nama variabel dengan nilainya:
sumber
Saya punya metode, dan meskipun bukan yang paling efisien ... itu berhasil! (dan itu tidak melibatkan modul mewah).
Pada dasarnya ini membandingkan ID Variabel Anda dengan global () ID Variabel , lalu mengembalikan nama pertandingan.
sumber
Jika tujuannya adalah untuk membantu Anda melacak variabel Anda, Anda dapat menulis fungsi sederhana yang memberi label pada variabel dan mengembalikan nilai dan jenisnya. Sebagai contoh, misalkan i_f = 3.01 dan Anda membulatkannya ke integer yang disebut i_n untuk digunakan dalam kode, dan kemudian membutuhkan string i_s yang akan masuk ke laporan.
Ini mencetak ke jendela di setiap panggilan untuk keperluan debugging dan juga menghasilkan string untuk laporan tertulis. Satu-satunya downside adalah bahwa Anda harus mengetik variabel dua kali setiap kali Anda memanggil fungsi.
Saya seorang pemula Python dan menemukan cara ini sangat berguna untuk mencatat upaya saya ketika saya memprogram dan mencoba untuk mengatasi semua objek dalam Python. Salah satu cacatnya adalah whatis () gagal jika ia memanggil fungsi yang dijelaskan di luar prosedur di mana ia digunakan. Misalnya, int (i_f) adalah panggilan fungsi yang valid hanya karena fungsi int diketahui oleh Python. Anda dapat memanggil whatis () menggunakan int (i_f ** 2), tetapi jika karena alasan yang aneh Anda memilih untuk mendefinisikan fungsi yang disebut int_squared, ia harus dideklarasikan di dalam prosedur di mana whatis () digunakan.
sumber
Mungkin ini bisa bermanfaat:
Fungsi melewati daftar ID nilai dari lingkup global (namespace dapat diedit), menemukan indeks var / fungsi yang diinginkan / diperlukan berdasarkan ID-nya, dan kemudian mengembalikan nama dari daftar nama global berdasarkan pada indeks yang diakuisisi.
sumber
Metode berikut tidak akan mengembalikan nama variabel tetapi menggunakan metode ini Anda dapat membuat bingkai data dengan mudah jika variabel tersedia dalam cakupan global.
sumber
Untuk konstanta, Anda dapat menggunakan enum, yang mendukung pengambilan namanya.
sumber
Saya mencoba untuk mendapatkan nama dari memeriksa penduduk setempat, tetapi tidak dapat memproses var seperti [1], b.val. Setelah itu, saya mendapat ide baru --- dapatkan nama var dari kode, dan saya coba succ! kode seperti di bawah ini:
sumber
Anda dapat mencoba yang berikut ini untuk mengambil nama fungsi yang Anda tetapkan (meskipun tidak berfungsi untuk fungsi bawaan):
sumber