


Menguasai Pengaturcaraan Meta Ajaib Python: Kod yang Menulis Sendiri
Keupayaan metaprogramming Python benar-benar menarik. Mereka membenarkan kami membengkokkan bahasa mengikut kehendak kami, mencipta kod yang menulis kod. Ia seperti mengajar Python untuk menjadi pengaturcara sendiri!
Mari kita mulakan dengan penjanaan kod. Di sinilah kita mencipta kod Python sebagai rentetan dan kemudian melaksanakannya. Ia mungkin terdengar mudah, tetapi ia sangat berkuasa. Berikut ialah contoh asas:
code = f"def greet(name):\n print(f'Hello, {{name}}!')" exec(code) greet("Alice")
Ini mencipta fungsi dengan cepat dan kemudian memanggilnya. Tetapi kita boleh pergi lebih jauh. Kami boleh menjana keseluruhan kelas, modul atau algoritma kompleks berdasarkan keadaan masa jalan.
Satu helah hebat ialah menggunakan penjanaan kod untuk konfigurasi. Daripada memuatkan fail konfigurasi, kami boleh menjana kod Python yang mentakrifkan tetapan kami. Ini boleh menjadi lebih pantas dan lebih fleksibel daripada penghuraian konfigurasi tradisional.
Sekarang, mari kita beralih kepada Pokok Sintaks Abstrak (AST). Di sinilah perkara menjadi sangat menarik. AST ialah perwakilan pokok kod Python. Kita boleh menghuraikan sumber Python ke dalam AST, mengubah suainya dan kemudian menyusunnya semula menjadi kod boleh laku.
Berikut ialah contoh mudah yang mengubah suai fungsi untuk menambah pengelogan:
import ast def add_logging(node): if isinstance(node, ast.FunctionDef): log_stmt = ast.Expr(ast.Call( func=ast.Attribute( value=ast.Name(id='print', ctx=ast.Load()), attr='__call__', ctx=ast.Load() ), args=[ast.Str(s=f"Calling {node.name}")], keywords=[] )) node.body.insert(0, log_stmt) return node tree = ast.parse("def hello(): print('Hello, world!')") modified_tree = ast.fix_missing_locations(ast.NodeTransformer().visit(tree)) exec(compile(modified_tree, '<string>', 'exec')) hello()
Ini menambah pernyataan cetakan pada permulaan setiap fungsi. Ini contoh mudah, tetapi ia menunjukkan kuasa manipulasi AST. Kita boleh menggunakan ini untuk semua jenis transformasi: mengoptimumkan kod, menambah instrumentasi atau bahkan melaksanakan ciri bahasa baharu.
Satu penggunaan manipulasi AST yang sangat menarik ialah mencipta bahasa khusus domain (DSL). Kita boleh menghuraikan sintaks tersuai menjadi AST, mengubahnya menjadi Python biasa, dan kemudian melaksanakannya. Ini membolehkan kami mencipta bahasa yang disesuaikan dengan masalah tertentu sambil memanfaatkan kuasa penuh Python.
Sebagai contoh, kita boleh mencipta DSL matematik mudah:
import ast class MathTransformer(ast.NodeTransformer): def visit_BinOp(self, node): if isinstance(node.op, ast.Add): return ast.Call( func=ast.Name(id='add', ctx=ast.Load()), args=[self.visit(node.left), self.visit(node.right)], keywords=[] ) return node def parse_math(expr): tree = ast.parse(expr) transformer = MathTransformer() modified_tree = transformer.visit(tree) return ast.fix_missing_locations(modified_tree) def add(a, b): print(f"Adding {a} and {b}") return a + b exec(compile(parse_math("result = 2 + 3 + 4"), '<string>', 'exec')) print(result)
Ini mengubah operasi tambah kepada panggilan fungsi, membolehkan kami menambah gelagat tersuai (seperti pengelogan) pada operasi matematik asas.
Satu lagi teknik yang berkuasa ialah manipulasi bytecode. Python menyusun kod sumber kepada bytecode sebelum melaksanakannya. Dengan memanipulasi kod bait ini, kami boleh mencapai pengoptimuman atau pengubahsuaian yang sukar atau mustahil pada peringkat kod sumber.
Berikut ialah contoh mudah yang mengubah suai fungsi untuk mengira berapa kali ia dipanggil:
import types def count_calls(func): code = func.__code__ constants = list(code.co_consts) constants.append(0) # Add a new constant for our counter counter_index = len(constants) - 1 # Create new bytecode new_code = bytes([ 101, counter_index, # LOAD_CONST counter 100, 1, # LOAD_CONST 1 23, # BINARY_ADD 125, counter_index, # STORE_FAST counter ]) + code.co_code # Create a new code object with our modified bytecode new_code_obj = types.CodeType( code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize + 1, code.co_flags, new_code, tuple(constants), code.co_names, code.co_varnames, code.co_filename, code.co_name, code.co_firstlineno, code.co_lnotab ) return types.FunctionType(new_code_obj, func.__globals__, func.__name__, func.__defaults__, func.__closure__) @count_calls def hello(): print("Hello, world!") hello() hello() print(hello.__code__.co_consts[-1]) # Print the call count
Ini mengubah suai kod bait fungsi untuk menambah pembilang setiap kali ia dipanggil. Ia agak tahap rendah, tetapi ia membenarkan beberapa pengoptimuman dan pengubahsuaian yang sangat hebat.
Satu bidang di mana metaprogramming benar-benar bersinar adalah dalam mencipta algoritma penyesuaian. Kita boleh menulis kod yang menganalisis prestasinya sendiri dan menulis semula dirinya untuk menjadi lebih cekap. Sebagai contoh, kita boleh mencipta fungsi pengisihan yang mencuba algoritma yang berbeza dan memilih yang terpantas untuk data semasa:
code = f"def greet(name):\n print(f'Hello, {{name}}!')" exec(code) greet("Alice")
Penyusun ini akan menyesuaikan diri secara automatik untuk menggunakan algoritma terpantas untuk data yang dilihatnya.
Metaprogramming juga boleh menjadi sangat berguna untuk ujian dan penyahpepijatan. Kami boleh menggunakannya untuk menjana kes ujian secara automatik, mengejek objek atau menambah instrumentasi pada kod kami.
Berikut ialah contoh mudah yang menjana kes ujian secara automatik untuk sesuatu fungsi:
import ast def add_logging(node): if isinstance(node, ast.FunctionDef): log_stmt = ast.Expr(ast.Call( func=ast.Attribute( value=ast.Name(id='print', ctx=ast.Load()), attr='__call__', ctx=ast.Load() ), args=[ast.Str(s=f"Calling {node.name}")], keywords=[] )) node.body.insert(0, log_stmt) return node tree = ast.parse("def hello(): print('Hello, world!')") modified_tree = ast.fix_missing_locations(ast.NodeTransformer().visit(tree)) exec(compile(modified_tree, '<string>', 'exec')) hello()
Ini menjana kes ujian rawak untuk fungsi tambah kami. Kami boleh melanjutkan ini untuk menganalisis AST fungsi dan menjana lebih banyak kes ujian disasarkan.
Salah satu aspek yang paling berkuasa dalam pengaturcaraan meta ialah keupayaannya untuk mengurangkan kod boilerplate. Kami boleh menulis kod yang menulis kod, mengautomasikan tugasan berulang dan memastikan pangkalan kod kami KERING (Jangan Ulangi Sendiri).
Sebagai contoh, kami boleh mengautomasikan penciptaan kelas data:
import ast class MathTransformer(ast.NodeTransformer): def visit_BinOp(self, node): if isinstance(node.op, ast.Add): return ast.Call( func=ast.Name(id='add', ctx=ast.Load()), args=[self.visit(node.left), self.visit(node.right)], keywords=[] ) return node def parse_math(expr): tree = ast.parse(expr) transformer = MathTransformer() modified_tree = transformer.visit(tree) return ast.fix_missing_locations(modified_tree) def add(a, b): print(f"Adding {a} and {b}") return a + b exec(compile(parse_math("result = 2 + 3 + 4"), '<string>', 'exec')) print(result)
Ini mencipta kelas baharu dengan medan dan pembayang jenis yang ditentukan. Kami boleh melanjutkan ini untuk menambah kaedah, sifat atau ciri kelas lain.
Metaprogramming bukan hanya tentang menulis kod yang menulis kod. Ini mengenai mencipta perisian yang lebih fleksibel, boleh disesuaikan dan berkuasa. Ia membolehkan kami mencipta rangka kerja yang boleh menyesuaikan diri dengan kes penggunaan yang berbeza, menjana kod yang dioptimumkan untuk senario tertentu dan mencipta bahasa khusus domain yang menjadikan tugasan rumit menjadi mudah.
Namun, dengan kuasa yang besar datang tanggungjawab yang besar. Metaprogramming boleh menjadikan kod lebih sukar untuk difahami dan nyahpepijat jika tidak digunakan dengan berhati-hati. Adalah penting untuk mendokumentasikan kod pengaturcaraan meta dengan teliti dan menggunakannya dengan bijak.
Kesimpulannya, pengaturcaraan meta dalam Python membuka dunia kemungkinan. Sama ada anda mengoptimumkan prestasi, mengurangkan boilerplate, mencipta DSL atau membina algoritma penyesuaian, teknik pengaturcaraan meta seperti penjanaan kod dan manipulasi AST ialah alat yang berkuasa dalam kit alat Python anda. Mereka membenarkan anda menulis kod yang melampaui biasa, mencipta perisian yang boleh menganalisis, mengubah suai dan memperbaiki dirinya sendiri. Semasa anda meneroka teknik ini, anda akan menemui cara baharu untuk menjadikan kod Python anda lebih fleksibel, cekap dan berkuasa berbanding sebelum ini.
Ciptaan Kami
Pastikan anda melihat ciptaan kami:
Pusat Pelabur | Hidup Pintar | Epos & Gema | Misteri Membingungkan | Hindutva | Pembangunan Elit | Sekolah JS
Kami berada di Medium
Tech Koala Insights | Dunia Epok & Gema | Medium Pusat Pelabur | Medium Misteri Membingungkan | Sains & Zaman Sederhana | Hindutva Moden
Atas ialah kandungan terperinci Menguasai Pengaturcaraan Meta Ajaib Python: Kod yang Menulis Sendiri. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

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

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Penyelesaian kepada Isu Kebenaran Semasa Melihat Versi Python di Terminal Linux Apabila anda cuba melihat versi Python di Terminal Linux, masukkan Python ...

Cara mengelakkan dikesan semasa menggunakan fiddlerevery di mana untuk bacaan lelaki-dalam-pertengahan apabila anda menggunakan fiddlerevery di mana ...

Apabila menggunakan Perpustakaan Pandas Python, bagaimana untuk menyalin seluruh lajur antara dua data data dengan struktur yang berbeza adalah masalah biasa. Katakan kita mempunyai dua DAT ...

Bagaimanakah Uvicorn terus mendengar permintaan HTTP? Uvicorn adalah pelayan web ringan berdasarkan ASGI. Salah satu fungsi terasnya ialah mendengar permintaan HTTP dan teruskan ...

Fastapi ...

Menggunakan Python di Terminal Linux ...

Bagaimana Mengajar Asas Pengaturcaraan Pemula Komputer Dalam masa 10 jam? Sekiranya anda hanya mempunyai 10 jam untuk mengajar pemula komputer beberapa pengetahuan pengaturcaraan, apa yang akan anda pilih untuk mengajar ...

Memahami Strategi Anti-Crawling of Investing.com Ramai orang sering cuba merangkak data berita dari Investing.com (https://cn.investing.com/news/latest-news) ...
