Cara Python Mengatur Data dan Perilaku
Python mendukung beberapa cara menyusun program. Procedural programming mengatur program sebagai urutan langkah. Functional programming mengolah data dengan fungsi. Object-oriented programming menyatukan data dan operasi yang berkaitan. Ketiganya dapat dipakai bersama.
Saat program berjalan, setiap nilai di Python merupakan objek. Bilangan, fungsi, class, dan modul memiliki tipe, identitas yang membedakannya dari objek lain, serta nilai yang disimpan.
Tipe sebuah objek menentukan atribut dan method yang tersedia. Karena aturan ini berlaku untuk semua objek, fungsi dapat disimpan dalam list, class dapat diberikan kepada fungsi lain, dan bilangan dapat memiliki method. Model objek Python dapat digunakan dalam program procedural, functional, maupun object-oriented.
Membandingkan Cara Menyusun Program
Model objek yang sama mendukung beberapa cara menyusun program. Gaya procedural menyusun langkah dan aliran data secara berurutan, gaya fungsional menyusun komputasi dari fungsi yang dipanggil berlapis, dan gaya berorientasi objek menyimpan data bersama operasi yang mengolahnya. Mengenali ketiganya membantumu menebak arah alur program saat membaca kode orang lain.
Procedural Programming
Dalam procedural programming, program disusun sebagai rangkaian operasi dengan aliran data yang jelas. Struktur data dan fungsi yang mengolahnya dapat ditulis secara terpisah, termasuk dalam bahasa yang mendukung class.
#include <stdio.h>
// Contoh pendekatan procedural dalam bahasa C
struct ParkSystem {
int max;
int occ;
};
int occupy(struct ParkSystem* ps) {
if (ps->max <= ps->occ) {
return -1;
}
ps->occ++;
return 0;
}
void leave(struct ParkSystem* ps) {
if (ps->occ > 0) {
ps->occ--;
}
}
int main() {
struct ParkSystem ps = {100, 0};
occupy(&ps);
printf("%d %d", ps.max, ps.occ);
return 0;
}Di sini, struct C menyimpan state parkir. Setiap fungsi menerima pointer ke data tersebut. Fungsi procedural dapat membaca input dan membiarkannya tetap sama.
Object Oriented Programming
Dalam object-oriented programming, class mengelompokkan data dan operasi yang saling berkaitan. Atribut menyimpan state objek, sedangkan method membaca atau memperbarui state tersebut.
# Contoh pendekatan object-oriented dalam Python
class ParkSystem:
def __init__(self, max_capacity):
self.max = max_capacity
self.occ = 0
def occupy(self):
if self.max <= self.occ:
return -1
self.occ += 1
return 0
def leave(self):
if self.occ > 0:
self.occ -= 1
# Penggunaan
ps = ParkSystem(100)
ps.occupy()
print(f"Max: {ps.max}, Occupied: {ps.occ}")Versi Python menyimpan aturan dan operasi parkir dalam satu class. Method occupy memeriksa kapasitas saat dipanggil. Namun, kode dari luar masih dapat mengubah atribut max dan occ secara langsung. Jadi, contoh singkat ini belum sepenuhnya melindungi state objek.
Functional Programming
Fungsi murni menghitung hasil dari input tanpa mengubah state. Pada versi ini, kapasitas dan jumlah kendaraan diberikan sebagai argumen, lalu fungsi mengembalikan jumlah tempat kosong.
def available_spaces(capacity, occupied):
return capacity - occupied
print(available_spaces(100, 1))
# Output: 99Sistem Parkir sebagai Contoh
Pada contoh ini, state objek menyimpan kapasitas maksimum dan jumlah tempat yang terisi. Method occupy mencatat mobil yang masuk, sedangkan leave mencatat mobil yang keluar.
class ParkingSystem:
def __init__(self, capacity):
"""Inisialisasi sistem parkir dengan kapasitas tertentu"""
if type(capacity) is not int or capacity <= 0:
raise ValueError("Kapasitas harus berupa bilangan bulat positif")
self.capacity = capacity
self.vehicles = [] # List kendaraan yang parkir
def park_vehicle(self, vehicle_plate):
"""Method untuk memarkir kendaraan"""
if vehicle_plate in self.vehicles:
return f"Kendaraan {vehicle_plate} sudah terparkir"
if len(self.vehicles) >= self.capacity:
return f"Parkir penuh! Tidak bisa parkir {vehicle_plate}"
self.vehicles.append(vehicle_plate)
return f"Kendaraan {vehicle_plate} berhasil parkir"
def exit_vehicle(self, vehicle_plate):
"""Method untuk mengeluarkan kendaraan"""
if vehicle_plate in self.vehicles:
self.vehicles.remove(vehicle_plate)
return f"Kendaraan {vehicle_plate} keluar parkir"
else:
return f"Kendaraan {vehicle_plate} tidak ditemukan"
def get_status(self):
"""Method untuk melihat status parkir"""
occupied = len(self.vehicles)
available = self.capacity - occupied
return {
'capacity': self.capacity,
'occupied': occupied,
'available': available,
'vehicles': tuple(self.vehicles)
}
def is_full(self):
"""Method untuk memeriksa apakah parkir penuh"""
return len(self.vehicles) >= self.capacity
# Contoh penggunaan
parking = ParkingSystem(5)
print(parking.park_vehicle("B 1234 CD"))
print(parking.park_vehicle("B 5678 EF"))
print(parking.get_status())
print(parking.is_full())Konsep Objek pada Tipe Data
"Setiap nilai adalah objek" berarti Python memakai satu model objek untuk seluruh nilai saat program berjalan. Atribut dan method yang tersedia tetap bergantung pada tipe objek tersebut.
Angka adalah Objek
Bilangan bulat adalah objek yang punya method. Contoh berikut memanggil bit_length() pada 42 lalu mencetak hasilnya.
# Angka di Python adalah objek
number = 42
# Angka memiliki method
print(number.bit_length()) # Method untuk menghitung bit length
print(number.__add__(8)) # Method penjumlahan (sama dengan number + 8)
# Angka float juga objek
price = 15.75
print(price.is_integer()) # Method untuk memeriksa apakah bilangan bulat
print(price.as_integer_ratio()) # Method untuk mengubah nilai menjadi rasio
# Bahkan hasil operasi matematika adalah objek
result = 10 + 5
print(type(result)) # <class 'int'>
print(dir(result)) # Menampilkan nama atribut untuk eksplorasiString adalah Objek
String adalah objek dengan method yang menghasilkan nilai baru. Contoh berikut memanggil beberapa method string pada satu teks.
# String di Python adalah objek dengan built-in method
message = "Belajar Python itu Menyenangkan"
# String memiliki banyak method
print(message.upper()) # BELAJAR PYTHON ITU MENYENANGKAN
print(message.lower()) # belajar python itu menyenangkan
print(message.title()) # Belajar Python Itu Menyenangkan
print(message.count('a')) # Menghitung huruf 'a'
print(message.replace('Python', 'Programming')) # Mengganti kata
# Method pemeriksaan
email = "user@example.com"
print(email.endswith('.com')) # True
print(email.startswith('user')) # True
print(email.find('@')) # Posisi karakter '@'
# Method formatting
name = "alice"
age = 25
formatted = "Nama: {}, Umur: {}".format(name.title(), age)
print(formatted)
# String split dan join
words = message.split() # Memecah teks menjadi list kata
print(words)
rejoined = " ".join(words) # Menggabung kembali
print(rejoined)List adalah Objek
List menyediakan method yang mengubah isi seperti append(), serta method pembacaan seperti count() yang tidak mengubah list. Contoh berikut berawal dari daftar buah lalu memanggil method list.
# List di Python adalah objek yang dinamis
fruits = ["apel", "jeruk", "mangga"]
# List memiliki method untuk mengubah data
fruits.append("pisang") # Menambah di akhir
print(fruits)
fruits.insert(1, "strawberry") # Menambah di posisi tertentu
print(fruits)
fruits.remove("jeruk") # Menghapus item tertentu
print(fruits)
# Method pencarian dan pengurutan
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(numbers.count(1)) # Menghitung kemunculan
print(numbers.index(4)) # Mencari posisi
numbers.sort() # Mengurutkan
print(numbers)
numbers.reverse() # Membalik urutan
print(numbers)
# List comprehension - cara pythonic
squares = [x**2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
# Method untuk operasi lanjutan
original = [1, 2, 3]
copy_list = original.copy() # Membuat salinan
original.extend([4, 5]) # Menambah beberapa item
print(f"Original: {original}")
print(f"Copy: {copy_list}")Dictionary adalah Objek
Dictionary adalah objek dengan method untuk membaca dan memperbarui pasangannya. Contoh berikut memakai data seorang mahasiswa untuk memanggil method tersebut.
# Dictionary di Python adalah objek yang fleksibel
student = {
"name": "Alice",
"age": 22,
"major": "Computer Science",
"gpa": 3.8
}
# Dictionary memiliki method untuk mengubah data
print(student.get("name")) # Mengambil value dengan aman
print(student.get("height", "Unknown")) # Default value jika key tidak ada
# Method untuk melihat isi dictionary
print(student.keys()) # Semua keys
print(student.values()) # Semua values
print(student.items()) # Pasangan key-value
# Method untuk memperbarui data
student.update({"semester": 6, "age": 23}) # Memperbarui beberapa nilai
print(student)
# Method pop untuk mengambil dan menghapus
gpa = student.pop("gpa")
print(f"GPA yang dihapus: {gpa}")
print(student)
# Dictionary comprehension
grades = {"Math": 85, "Physics": 92, "Chemistry": 78}
passed = {subject: grade for subject, grade in grades.items() if grade >= 80}
print(passed)
# Dictionary bertingkat
university = {
"students": {
"CS": ["Alice", "Bob"],
"Math": ["Charlie", "Diana"]
},
"location": "Jakarta"
}
print(university["students"]["CS"])Fungsi sebagai Objek
Fungsi dapat diberikan sebagai argumen, disimpan di dalam collection, dan ditempatkan pada variabel seperti nilai lain.
# Fungsi di Python dapat diperlakukan seperti nilai lain
def greet(name):
return f"Hello, {name}!"
def farewell(name):
return f"Goodbye, {name}!"
# Fungsi memiliki atribut
print(greet.__name__) # Nama fungsi
print(type(greet)) # <class 'function'>
# Fungsi bisa disimpan dalam variable
my_function = greet
print(my_function("Alice")) # Hello, Alice!
# Fungsi dapat disimpan dalam list
functions = [greet, farewell]
for func in functions:
print(func("Bob"))
# Fungsi bisa dijadikan parameter
def call_function(func, name):
return func(name)
result = call_function(greet, "Charlie")
print(result)
# Fungsi bisa dikembalikan dari fungsi lain
def get_greeting_function(language):
def english_greet(name):
return f"Hello, {name}!"
def indonesian_greet(name):
return f"Halo, {name}!"
if language == "english":
return english_greet
if language == "indonesian":
return indonesian_greet
raise ValueError(f"Bahasa tidak didukung: {language}")
# Menggunakan fungsi yang dikembalikan
greet_func = get_greeting_function("indonesian")
print(greet_func("Diana")) # Halo, Diana!
# Lambda function juga objek
square = lambda x: x ** 2
print(type(square)) # <class 'function'>
print(square(5)) # 25Class dan Instance sebagai Objek
Class menentukan cara instance dibuat serta menyediakan class attribute dan method yang dipakai bersama. Class itu sendiri juga merupakan objek, sedangkan setiap instance menyimpan state masing-masing.
# Mendefinisikan class sebagai blueprint
class Student:
# Class attribute yang dipakai semua instance
university = "Universitas Indonesia"
def __init__(self, name, major, semester):
# Instance attribute yang berbeda pada setiap instance
self.name = name
self.major = major
self.semester = semester
self.courses = []
def add_course(self, course):
"""Method untuk menambah mata kuliah"""
self.courses.append(course)
return f"{self.name} mengambil mata kuliah {course}"
def get_info(self):
"""Method untuk mendapatkan informasi mahasiswa"""
return {
'name': self.name,
'major': self.major,
'semester': self.semester,
'courses': tuple(self.courses),
'university': self.university
}
def __str__(self):
"""Special method untuk representasi string"""
return f"Student({self.name}, {self.major})"
def __len__(self):
"""Special method untuk mendapatkan jumlah mata kuliah"""
return len(self.courses)
# Membuat instance dari class
student1 = Student("Alice", "Computer Science", 4)
student2 = Student("Bob", "Mathematics", 6)
# Setiap instance adalah objek dengan attribute dan method
print(student1.add_course("Python Programming"))
print(student1.add_course("Data Structures"))
print(student2.add_course("Calculus"))
print(student2.add_course("Linear Algebra"))
# Menggunakan method
print(student1.get_info())
print(student2.get_info())
# Special method (__str__ dan __len__)
print(student1) # Student(Alice, Computer Science)
print(len(student1)) # 2 (jumlah mata kuliah)
# Instance memiliki attribute yang dapat diakses
print(f"Nama: {student1.name}")
print(f"Jurusan: {student1.major}")
print(f"Universitas: {student1.university}")
# Class juga merupakan objek
print(type(Student)) # <class 'type'>
print(Student.__name__) # Student
print(Student.university) # Universitas IndonesiaSpecial Methods
Nama special method dimulai dan diakhiri dengan double underscore, seperti __len__. Python memanggil method ini melalui sintaks atau built-in function seperti +, abs(), repr(), dan bool(). Tambahkan special method hanya jika operasi tersebut memang masuk akal untuk objek yang dibuat.
from math import hypot
class Vector2D:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
"""Representasi yang mudah dibaca manusia."""
return f"({self.x}, {self.y})"
def __repr__(self):
"""Representasi eksplisit untuk debugging."""
return f"Vector2D(x={self.x!r}, y={self.y!r})"
def __abs__(self):
"""Mengembalikan panjang vektor."""
return hypot(self.x, self.y)
def __eq__(self, other):
"""Membandingkan koordinat dengan Vector2D lain."""
if not isinstance(other, Vector2D):
return NotImplemented
return self.x == other.x and self.y == other.y
def __add__(self, other):
"""Mengembalikan vektor baru berisi jumlah per koordinat."""
if not isinstance(other, Vector2D):
return NotImplemented
return Vector2D(self.x + other.x, self.y + other.y)
def __bool__(self):
"""Mengembalikan False untuk vektor nol dan True untuk vektor lainnya."""
return bool(self.x or self.y)
pertama = Vector2D(3, 4)
kedua = Vector2D(1, -2)
print(pertama) # (3, 4) melalui __str__
print(repr(pertama)) # Vector2D(x=3, y=4)
print(abs(pertama)) # 5.0 melalui __abs__
print(pertama == Vector2D(3, 4)) # True melalui __eq__
gabungan = pertama + kedua # __add__ menghasilkan vektor baru
print(gabungan) # (4, 2)
print(pertama) # (3, 4), tidak berubah
nol = Vector2D(0, 0)
print(bool(pertama)) # True
print(bool(nol)) # FalsePraktik Object Oriented Programming
Contoh berikut menggabungkan beberapa class untuk memodelkan buku, anggota, dan proses peminjaman di perpustakaan.
| Tahap | Buku pertama | Pinjaman Alice |
|---|---|---|
| Sebelum peminjaman | Tersedia, tanpa peminjam | Kosong |
Setelah borrow_book() | Dipinjam oleh Alice | Memuat buku pertama |
Setelah return_book() | Tersedia kembali | Kosong |
Judul, penulis, dan kode buku pada contoh ini adalah data latihan. Daftar buku dan anggota tetap berupa atribut publik. Contoh mengajarkan hubungan objek, bukan penyimpanan multiuser.
class Book:
def __init__(self, title, author, isbn):
self.title = title
self.author = author
self.isbn = isbn
self.is_borrowed = False
self.borrower = None
def __str__(self):
status = "Dipinjam" if self.is_borrowed else "Tersedia"
return f"{self.title} oleh {self.author} - {status}"
class Member:
def __init__(self, name, member_id):
self.name = name
self.member_id = member_id
self.borrowed_books = []
def __str__(self):
return f"Member: {self.name} (ID: {self.member_id})"
class Library:
def __init__(self, name):
self.name = name
self.books = []
self.members = []
def add_book(self, book):
"""Menambah buku ke perpustakaan"""
self.books.append(book)
return f"Buku '{book.title}' berhasil ditambahkan"
def register_member(self, member):
"""Mendaftarkan anggota baru"""
self.members.append(member)
return f"Anggota {member.name} berhasil didaftarkan"
def borrow_book(self, member_id, isbn):
"""Meminjam buku"""
# Cari anggota
member = None
for m in self.members:
if m.member_id == member_id:
member = m
break
if member is None:
return "Anggota tidak ditemukan"
# Cari buku
book = None
for b in self.books:
if b.isbn == isbn and not b.is_borrowed:
book = b
break
if book is None:
return "Buku tidak tersedia"
# Proses peminjaman
book.is_borrowed = True
book.borrower = member
member.borrowed_books.append(book)
return f"{member.name} berhasil meminjam '{book.title}'"
def return_book(self, member_id, isbn):
"""Mengembalikan buku"""
member = None
for m in self.members:
if m.member_id == member_id:
member = m
break
if member is None:
return "Anggota tidak ditemukan"
book = None
for b in member.borrowed_books:
if b.isbn == isbn:
book = b
break
if book is None:
return "Buku tidak ditemukan dalam daftar pinjaman"
# Proses pengembalian
book.is_borrowed = False
book.borrower = None
member.borrowed_books.remove(book)
return f"{member.name} berhasil mengembalikan '{book.title}'"
def get_available_books(self):
"""Mendapatkan daftar buku yang tersedia"""
available = [book for book in self.books if not book.is_borrowed]
return available
def get_member_books(self, member_id):
"""Mendapatkan daftar buku yang dipinjam anggota"""
for member in self.members:
if member.member_id == member_id:
return list(member.borrowed_books)
return []
# Contoh penggunaan sistem perpustakaan
library = Library("Perpustakaan Central")
# Menambah buku
book1 = Book("Python Programming", "John Smith", "978-1234567890")
book2 = Book("Data Science Basics", "Jane Doe", "978-0987654321")
book3 = Book("Machine Learning", "Bob Johnson", "978-1122334455")
print(library.add_book(book1))
print(library.add_book(book2))
print(library.add_book(book3))
# Mendaftarkan anggota
member1 = Member("Alice Cooper", "M001")
member2 = Member("Bob Wilson", "M002")
print(library.register_member(member1))
print(library.register_member(member2))
# Meminjam buku
print(library.borrow_book("M001", "978-1234567890"))
print(library.borrow_book("M002", "978-0987654321"))
# Melihat status buku
print("\nDaftar semua buku:")
for book in library.books:
print(book)
print("\nBuku yang tersedia:")
for book in library.get_available_books():
print(book)
print(f"\nBuku yang dipinjam Alice: {len(library.get_member_books('M001'))} buku")
# Mengembalikan buku
print(library.return_book("M001", "978-1234567890"))Karena semua nilai mengikuti model objek yang sama, fungsi dan class dapat disimpan dalam variabel, dimasukkan ke list, atau diberikan sebagai argumen seperti nilai lain. Gunakan object-oriented programming ketika data dan operasi terkait perlu dikelola bersama. Gunakan procedural programming atau functional programming ketika urutan langkah atau aliran datanya lebih mudah dijelaskan secara langsung.