Function, Building and Block of Code
Namespace
Namespace adalah pemetaan nama-nama ke objek-objek. Contohnya kumpulannames
bawaan (fungsi yang dapat diakses dimana saja program python manapun) seperti help()
, dir()
atau print()
, global names
dalam sebuah module, dann local name
pada sebuah function. Bahkan kumpulan dari attributes dari sebuah objek dapat disebut juga dengan namespace.
Info
names
artinya varibael. Sebuah nama yang menampung objek.
Manfaat dari namespace ini, kita dapat mendefinisikan dan mengelola names secara jelas. Misalkan kita ingin fungsi menggunakan fungsi standard_normal
, dan kita harus mengimport from numpy.random import standard_normal
.
Inline syntax diatas dimulai dengan masuk ke namespace numpy
, lalu masuk lagi ke namespace terakhir random
dan terakhir memanggil names yang ingin kita gunakan, yaitu standard_nomal
.
Ada konsep lain yang berhubungan denga namespace, yaitu scope.
Scope
Scope adalah wilayah tekstual dari program python, dimana namespace dapat diakses secara langsung. Scope ditetukan secara statis, namun sebenarnya, mereka menentukannya dinamis. Artinya, jika kita menginspeksi ke kode yang ditulis dengan python kita dapat mengetahui names scope dari objek tersebut. Misalkan standard_normal
berasal dari objek numpy
.
Ada empat scope yang python buat dapat diakses.
-
Local, scope paling dalam dan mengadung local names
-
enclosing, scope ini mengadung enclosing names. diantara global dan local scope.
-
global, scope yang mengandung global scope
-
built-in, scope yang mengandung built-in names, semisal
prin
,abs
,help
,die
dst.
Aturan python mencari sebuah names yang ditulis pada program python sebagai berikut :
Pertama, python akan mencari dari namespace saat ini. Jika tidak ditemukan selanjutnya akan dicari pada enclosing scope, dan terus hingga buil-in scope. JIka names juga tidak ditemukan maka python akan mengeluarkan exception NameError
yang artinya names tersebut belum terdefinisi.
Urutanya pencarian name, LEGB, (Local,Enclosing ,Global, Built-in)
Scope dan Name Resolution
Diatas kita berbicara tentang teori, sekarang kita akan langsung bermain dengan program python. Lihatlah kode dibawah ini.
Code
variable test pada pada my_function
menghasilkan nilai 1
karena didefinisikan pada local scope dan test pada global scope adalah 0
karena test terdefinisi pada global scope. Ingat, Python akan mencari name pada masing-masing namespace saat ini. Artinya python akan mencari name testmy_function
di localscope, dan name test pada global di global scope.
Code
Kode diatas, name test pada my_function
menjadi 0
. Ingat LEGB, karena python tidak menemukan test pada localscope (current scope fungsi tersebut) selanjutnya python akan mencari di enclosing scope, karena fungsi diatas tidak memliki enclosing scope selanjutnya python akan mencari test pada global scope dan menemukanya dengan nilai test adalah 0
.
Sekarang lihat kode dibawah ini untuk demo yang lebih tajam
Code
Kali ini, karena python tidak menesmukan name test dari fungsi inner
maka akan mencari name test pada enclosing
scope, yaitu pada fungsi outer.
Global dan Nonlocal Statement
Just look at the behavior of nonlocal and global
nonlocal
-
The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals.
Code
And now for global. Menggunakan kode yang sama diatas. Coba kita comment name test pada inner()
. Merujuk ke LEGB, python akan mengambil nilai test pada enclosing scope, yaitu name test pada outer()
dengan nilai 1.
Code
Namun dengan membuat global naming test pada fungsi inner()
membuat python mengambil nilai test langsung dari global.
Code
Dan jika kita uncomment lagi name test pada inner
dan menulis global pada test maka nilai test pada global akan di overwrite dengan nilai test pada `#!python inner.
Code
Input Parameters
Untuk memahami semua tipe parameter anda harus memahami apa itu maksud dari memberikan argumen pada sebuah fungsi. Ada 3 kunci yang harus anda pahami;
- Argument-passing, memberikan nilai dari objek ke variable name pada local scope fungsi.
- Mengisi nilai dari objek ke argument name didalam fungsi tidak memberikan dampak pada caller.
- Mengubah argumen mutable object pada sebuah fungsi akan mempengaruhi caller.
Argument-passing
Memberikan nilai dari objek ke variable name pada local scope fungsi.
Assignment to parameter name
Mengisi nilai dari objek ke argument name didalam fungsi tidak memberikan dampak pada caller.
Code
- Assignment
x
ini hanya terjadi pada local scope, tidak mempengaruhi global scope (caller). - Nilai global
x
tetap 10, tidak dipengaruhi asiggment didalam fungsiganda
.
Mengubah mutable objek
Mengubah argumen mutable object pada sebuah fungsi akan mempengaruhi caller.
Code
Jika kembali melihat poin kedua "=Mengisi= nilai dari objek ke argument name didalam fungsi tidak memberikan dampak pada caller.". Lihat kode dibawah ini, saya menambahkan kode yang mengisi nilai x
dengan nilai baru.
Code
lst = [1,2,3,4,5]
def func(x):
for a,b in enumerate(x):
lst[a] = b**2
x = [0,0,0,0,0] #(1)!
func(lst)
print(lst) #(2)!
- Tidak dapat mengganti nilai caller,
lst
pada global scope yang sudah dimodifikasi. - Tetap mengambil nilai
lst
pada global scope yang sudah dimodifikasi oleh fungsifunc
.
Memberikan argumen
Ada empat cara untuk memberikan sebuah argumen pada fungsi
- Positional arguments
- Keyword arguments
- Iterable unpacking
- Dictionary unpacking
Positional arguments
Ini adalah pemberian argumenyang paling umum.
Code
- Penempatan argumen sesuai posisi
Keyword arguments
Ketika memberikan argumen pada sebuah fungsi, keyword argumen tidak harus dalam urutan.
Code
- Penempatan argumen sesuai nama dari argumen
Anda juga dapat menggabungkan positional argument dan keyword argumen.
Code
- 10, adalah positional argumen, dan {20,30} menggunakan keyword argumen.
Warning
Jika anda ingin menggabungkan positional dan keyword argumen pastikan positional argumen harus ditempatkan sebelum keyword. Kalau tidak akan menyebabkan syntax error
Code
- 30, adalah positional argumen, dan {10,20} menggunakan keyword argumen.
Iterable unpacking
Untuk menggunakan iterable unpacking anda dapat menggunakan tanda bintang =*= sebelum nama variabel yang menampung objek iterable. Iterable unpacking akan memberikan argumen sesuai dengan posisi dari iterable yang diberikan.
Code
Dictionary unpacking
Sejenis dengan iterable unpacking yang memberikan argumen sesuai dengan posisi, Dictionary unpacking memberikan nilai sesuai dengan keyword argument. Yang harus diingat, key yang digunakan pada Dictionary akan diberikan pada keyword argument yang sesuai.
Code
Kombinasi tipe argumen
Kita dapat menggabungkan antara keyword anda positional selama kita menempatkan dalam urutan yang benar. Kita juga dapat mengkombinasi Ditctionary dan Iterable unpacking dengan positional dan keyword argumen dengan ketentuan sebagai berikut;
- Posisi awal, bisa positional argument
(name)
dan iterable unpacking*(name)
- Selanjutnya, keyword argument
(name=value)
yang dapat digabung dengan iterable unpacking*(name)
- Terakhir, dictionary unpacking
**{name:value}
yang dapat digabung dengan keyword argument(name=value)
Code
Mendefinisikan parameter
Parameter pada fungsi terbagi menjadi 5 kelompok
-
Positional atau Keyword parameter, dapat diberikan oleh positional argumen dan keyword argument
-
Variable Positional Parameters, menerima kumpulan nilai dari positional argument dalam sebuah
tuple
-
Variable Keyword parameters, menerima kumpulan nilai dari keyword argument dalam sebuah
dictionary
-
Positional-only parameters, hanya dapat menerima positional arguments.
-
Keyword-only parameters, hanya dapat menerima keyword arguments
Parameter opsional
Diluar dari kategori parameter diatas, parameter dapat diatur untuk menjadi opsional atau wajib. Parameter Opsional memeliki nilai bawaan yang harus didefinisikan pada parameter fungsi dengan syntax name=value
.
Code
Penting untuk dicatat bahwa, paramter yang wajib harus diletakan dibagian yang paling kiri dan tidak bisa disebalah kanan dari parameter yang opsi. Dibawah ini saya menghapus parameter opsi c
dan merubahnya menjadi parameter wajib.
Code
Variable Positional Parameter
Dalam kondisi tertentu mungkin tidak ingin menspesifikan dengan tepat jumlah positional parameter pada sebuah fungsi. Python menyediakan sebuah fitur untuk menyelesaikan diatas dengan varible positional paramters.
Code
def terkecil (*post):
# print(type(post)) (1)
if post:
terkecil = post[0] # Terkecil sementara
for a in post[1:]:
if a < terkecil:
terkecil = a
return terkecil
print(terkecil(1,-2,4,-5,6))
- Variable Positional Parameters akan mengumpulkan argumen yang diterima menjadi sebuah
tuple
.
Info
Fungsi setidaknya hanya dapat memiliki satu buah variable positional parameters. Karena python tidak tahu bagaimana membagi argumen-argumen yang diberikan menjadi dua atau lebih tuple. anda jgua tidak dapat menetapkan nilai bawaan pada variable positional parameters. Nilai default variable positional parameter adalah empty tuple.
Jika anda perhatikan, penggunaan variable positional parameters sama dengan iterable unpacking. Kedua fitur tersebut seringkali digunakan secara bersamaan. Dimana variabel positional parameters memastikan panjang dari iterable yang di unpacking cocok dengan jumlah parameter yang terdifinisi disebuah fungsi.
Code
def terkecil (*post): #(1)!
if post:
terkecil = post[0] # Terkecil sementara
for a in post[1:]:
if a < terkecil:
terkecil = a
return terkecil
deret = [1,-2,3,-4,5,6]
print(terkecil(*deret)) #(2)!
- Varriable Positional Parameters
- Itrable Unpacking
Variable Keyword Parameters
Sama dengan variable positional parameters, yang berbeda adalah fitur ini mengumpulkan parameter dalam bentuk dictionary dan menggunakan dua buah asterik **
.
Sama seperti variable positional paramters yang mengumpulkan kembali iterable unpacking, variable keyword parameters mengumpulkan kembali dictionary unpacking. Dictionary unpacking juga sering digunakan untuk memberikan argumen ke fungsi dengan variable keyword parameters.
Code
def connect(**options):
conn_params = {
'host': options.get('host', '127.0.0.1'),
'port': options.get('port', 5432),
'user': options.get('user', ''),
'pwd': options.get('pwd', ''),
}
print(conn_params)
# we then connect to the db (commented out)
# db.connect(**conn_params)
connect()
connect(host='127.0.0.42', port=5433)
connect(port=5431, user='fab', pwd='gandalf')
Didalam fungsi, kita dapat menyiapkan dictionary untuk parameter connection (conn_params) menggunakan nilai bawaan yang dapat ditiban.
Positional-only parameters
Untuk mengindikasi parameter pada sebuah fungsi harus sesuai dengan urutan posisi dan melarang menggunakan keyword argument gunakan syntax /
.
Code
- parameter
a
danb
harus diisi dengan positional argumen, jika tidak akan menghasilkan exception.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [337], in <cell line: 7>()
4 func(1,2,c=3)
5 func(*(2,4), 8)
----> 7 func(a=1,b=2,c=3)
TypeError: func() got some positional-only arguments passed as keyword arguments: 'a, b'
Info
Parameter disebelah slash /
adalah parameter yang ditetapkan sebagai positional-only parameters.
Positional-only parameters juga dapat menerima default value, menjadi parameter opsional.
Warning
Ingat tentang parameter opsional ?, parameter opsional harus diletakan disebelah kanan dari parameter wajib.
Combining Input Parameters
Mengkombinasi argumen dengan tipe yang berbeda pada fungsi yang sama ada beberapa batasan dalam urutan, diantaranya:
-
Positional only parameters harus ditempatkan diawal, diikut dengan
/
-
Normal parameters ditempatkan setelah Positional only paramaters.
- Variable positional parameters ditempatkan setelah normal parameters.
- Keyword only parameters ditempatkan setelah variable positional paramaters
- Variable keyword parameters selalu ditempatkan dibagian yang paling akhir.
- Untuk positional only parameters and norma paramenters, semua parameter wajib harus didefinisi sebelum parameter opsional Artinya, jika anda memliki positional only parameters opsional, maka semua normal parameter harus opsional.
Code
Bugs pada nilai default objek mutanble
Katakan kita memliki fungsi dibawahi ini
Code
Parameter defalut diatas selalu update ketika memanggil fungsi yang sama. Behavior yang diingikan nilai default tersebut selalu refresh, diperbaharui.
Code
Retrun value
Recursive function
Ketika fungsi memanggil dirinya sendiri untuk menghasilkan nilai return maka itu dikatakan Recursive function
Code
Info
Jika anda bingung, anda bisa merujuk ke catatan tambahan Recursive Function Python
Anonymous Function
Anonymouse function didalam python disebut dengan lambda. Penggunaan fitur ini bermanfaat jika kita hanya ingin membuatsebuah fungsi simple, ditulis hanya dengan satu baris. Untuk membuat fungsi ini gunakan syntax dibawah ini;
Oke, dibawah ini contoh implementasi penggunan lambda. Katakan kita ingin membuat sebuah fungsi untuk mengembalikan nilai genap.
Code
Pada baris yang di hightlight kita menggunakan lambda function untuk mengembalikan nilai mana saja yang genap. Pada fungsi lambda diatas kita meenggunakan fitur yang telah kita bahas, Pada pemanggilan fungsi jumlah(*range(20))
kita menggunakan iterable unpacking, pada penetuan parameter lambda lambda *lists :
menggunakan variable positional pamater, dan pada expression lambda menggunakan comprehension.
Function attributes
Setiap fungsi, khususnya pada sebuah objek yang besar memiliki atribut-atribut. Beberapa dari atribute tersebut dapat digunakan untuk meng-inspeksi fungsi tersebut saat runtime. attribute yang paling sering digunakan adalah
__doc__, __name__, __qualname__, __module__, __defaults__, __code__, __globals__, __dict__, __closure__, __annotations__, __kwdefaults__, __builtins__
.
Misalkan kita ingin mendapatkan dokumentasi dari objek pow
Built-in function
Python memliki fungsi bawaan yang dapat kita akses dari mana saja. Kita telah meyinnggunya pada Scope dan Name Resoulution ketika membahas bagaimana python mencari sebuah names dengan urutan Local, Enclosing, Global dan Built-in.
Untukmelihat daftar fungsi built_in anda dapat menggunakan dir()
pada attribute __builtins__
.
Code
- Saya hanya mengambil built-in function beberapa saja.
Dokumentasi Kode
Saat membahas tentang attribute kita menggunakan contaoh attribute #!__doc__
. Sekarang kita akan membahas cara membuat dokumentasi sehingga bisa diakes menggunakan attribute #!__doc__
atau fungsi built-in fungsi #!help()
.
Untuk membuat dokumentasi anda dapat mengikuti contoh dibawah.
Code
def contoh_doc(nama, tempat):
""" Contoh dokumentasi
Ini adalah dokumentasi yang berisikan penjelasan tentang fungsi ini. Fungsi ini,
Fungsi ini,Fungsi ini,Fungsi ini,Fungsi ini,Fungsi ini.
:param nama: Pembuat dokumentasi
:param tempat: Tempat membuat dokumentasi
:return: String detail hasil fungsi ini
"""
return f'Nama {nama}, tempat {tempat}'
help(contoh_doc)
# Sama dengan print(contoh_doc.__doc__)
Import Objects
Tujuan utama kita membuat seuah fungsi adalah untuk dapat digunakan kembali tanpa harus menulis ulang kode dimanampun python program ditulis. Di python kita harus mengimport mereka (fungsi-fungsi dalam sebuah object atau module) dalam bentuk namespace
di tempat dimana kita membutuhkan fungsi tersebut. Ada beberapa cara untuk mengimport objects dalam bentuk namespace
, yang paling sering dipakai adalah.
import module_name
from module_name import function_name