Saya baru saja beralih ke Pycharm dan saya sangat senang dengan semua peringatan dan petunjuk yang diberikannya untuk memperbaiki kode saya. Kecuali untuk yang ini saya tidak mengerti:
This inspection detects shadowing names defined in outer scopes.
Saya tahu itu praktik buruk untuk mengakses variabel dari lingkup luar tetapi apa masalah dengan membayangi lingkup luar?
Ini adalah satu contoh, di mana Pycharm memberi saya pesan peringatan:
data = [4, 5, 6]
def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
print data
print_data(data)
python
coding-style
pycharm
Framester
sumber
sumber
Jawaban:
Bukan masalah besar dalam cuplikan di atas, tetapi bayangkan sebuah fungsi dengan beberapa argumen dan beberapa baris kode. Kemudian Anda memutuskan untuk mengubah nama
data
argumen Anda sebagaiyadda
tetapi melewatkan salah satu tempat yang digunakan dalam fungsi fungsi ... Sekarangdata
mengacu pada global, dan Anda mulai memiliki perilaku aneh - di mana Anda akan memiliki jauh lebih jelasNameError
jika Anda tidak memiliki nama globaldata
.Juga ingat bahwa dalam Python semuanya adalah objek (termasuk modul, kelas, dan fungsi) sehingga tidak ada ruang nama yang berbeda untuk fungsi, modul, atau kelas. Skenario lain adalah Anda mengimpor fungsi
foo
di bagian atas modul Anda, dan menggunakannya di suatu tempat di badan fungsi Anda. Kemudian Anda menambahkan argumen baru ke fungsi Anda dan menamainya - nasib buruk -foo
.Akhirnya, fungsi dan tipe bawaan juga hidup di namespace yang sama dan dapat dibayangi dengan cara yang sama.
Tak satu pun dari ini banyak masalah jika Anda memiliki fungsi pendek, penamaan yang baik dan cakupan unittest yang layak, tetapi baik, kadang-kadang Anda harus mempertahankan kode kurang sempurna dan diperingatkan tentang masalah yang mungkin dapat membantu.
sumber
nonlocal
kata kunci untuk membuat rujukan skor luar (seperti pada penutupan) secara eksplisit. Perhatikan bahwa ini berbeda dari membayangi, karena secara eksplisit tidak membayangi variabel dari luar.Jawaban yang saat ini paling banyak dipilih dan diterima dan sebagian besar jawaban di sini tidak tepat.
Tidak masalah berapa lama fungsi Anda, atau bagaimana Anda memberi nama variabel secara deskriptif (semoga meminimalkan kemungkinan tabrakan nama potensial).
Fakta bahwa variabel lokal fungsi Anda atau parameternya terjadi untuk membagikan nama dalam lingkup global sama sekali tidak relevan. Dan faktanya, tidak peduli seberapa hati-hati Anda memilih nama variabel lokal, fungsi Anda tidak akan pernah dapat memperkirakan "apakah nama keren saya
yadda
juga akan digunakan sebagai variabel global di masa mendatang?". Solusinya? Jangan khawatir tentang itu! Pola pikir yang benar adalah merancang fungsi Anda untuk menggunakan input dari dan hanya dari parameternya di tanda tangan , dengan begitu Anda tidak perlu peduli dengan apa (atau akan) dalam lingkup global, dan kemudian membayangi menjadi bukan masalah sama sekali.Dengan kata lain, masalah bayangan hanya penting ketika fungsi Anda perlu menggunakan nama variabel lokal DAN variabel global yang sama. Tetapi Anda harus menghindari desain semacam itu sejak awal. Kode OP TIDAK benar-benar memiliki masalah desain seperti itu. Hanya saja PyCharm tidak cukup pintar dan mengeluarkan peringatan untuk berjaga-jaga. Jadi, hanya untuk membuat PyCharm senang, dan juga membuat kode kita bersih, lihat solusi ini mengutip dari jawaban silyevsk untuk menghapus variabel global sepenuhnya.
Ini adalah cara yang tepat untuk "menyelesaikan" masalah ini, dengan memperbaiki / menghapus hal global Anda, tidak menyesuaikan fungsi lokal Anda saat ini.
sumber
print_data
IS adalah variabel global. Pikirkan tentang hal itu ...Solusi yang baik dalam beberapa kasus mungkin untuk memindahkan kode vars + ke fungsi lain:
sumber
Tergantung berapa lama fungsinya. Semakin lama fungsinya, semakin besar peluang seseorang memodifikasinya di masa depan akan menulis
data
berpikir bahwa itu berarti global. Sebenarnya itu berarti lokal tetapi karena fungsinya begitu lama tidak jelas bagi mereka bahwa ada lokal dengan nama itu.Sebagai contoh fungsi Anda, saya pikir membayangi global tidak buruk sama sekali.
sumber
Melakukan hal ini:
sumber
sumber
data
, semua dalam beberapa ratus baris kode?data
adalah nama lokal dalam hal ini fungsi, jadi saya tidak repot-repot memeriksa / mengingat apakah global dengan nama yang sama eksis , apalagi apa yang dikandungnya.False
- jika Anda tidak mendefinisikan, tapi hanya mencoba untuk menggunakandata
, terlihat melalui cakupan sampai menemukan satu, sehingga tidak menemukan globaldata
.data = [1, 2, 3]; def foo(): print(data); foo()
Saya suka melihat tanda centang hijau di sudut kanan atas di pycharm. Saya menambahkan nama variabel dengan garis bawah hanya untuk menghapus peringatan ini sehingga saya dapat fokus pada peringatan penting.
sumber
Sepertinya pola kode 100% pytest
Lihat:
https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
Saya memiliki masalah yang sama dengan, ini sebabnya saya menemukan posting ini;)
Dan itu akan memperingatkan
This inspection detects shadowing names defined in outer scopes.
Untuk memperbaikinya, cukup pindahkan
twitter
perlengkapan ke./tests/conftest.py
Dan hapus
twitter
fixture seperti di./tests/test_twitter2.py
Ini akan membuat QA, Pycharm, dan semua orang senang
sumber