Cara mengakses variabel dari fungsi lain di kelas yang sama dengan python

Bab ini diambil dari buku A Primer on Scientific Programming with Python oleh H. P. Langtangen, edisi ke-5, Springer, 2016

Kelas dapat digunakan untuk banyak hal dalam komputasi ilmiah, tetapi salah satu tugas pemrograman yang paling sering dilakukan adalah merepresentasikan fungsi matematika yang memiliki sekumpulan parameter selain satu atau lebih variabel independen. Bagian ini menjelaskan mengapa fungsi matematika seperti itu menimbulkan kesulitan bagi pemrogram, dan bagian ini menunjukkan bagaimana ide kelas mengatasi kesulitan ini. Bagian menyajikan contoh lain di mana kelas mewakili fungsi matematika. Materi lebih lanjut tentang kelas, yang bagi beberapa pembaca mungkin mengklarifikasi ide, tetapi juga dapat dilewati dalam bacaan pertama, muncul di bagian dan bagian

Tantangan. fungsi dengan parameter

Untuk memotivasi konsep kelas, kita akan melihat fungsi dengan parameter. Salah satu contohnya adalah \[ y[t]=v_0t-\frac{1}{2}gt^2 \]. Secara konseptual, dalam fisika, besaran \[ y \] dipandang sebagai fungsi dari \[ t \], tetapi \[ y \] juga bergantung pada dua parameter lain, \[ v_0 \] dan \[ g \], meskipun . Kita dapat menulis \[ y[t;v_0,g] \] untuk menunjukkan bahwa \[ t \] adalah variabel independen, sedangkan \[ v_0 \] dan \[ g \] adalah parameter. Sebenarnya, \[ g \] adalah parameter tetap [selama kita berada di permukaan bumi dan dapat melihat \[ g \] sebagai konstanta], jadi hanya \[ v_0 \] dan \[ t \] yang dapat . Maka akan lebih baik untuk menulis \[ y[t;v_0] \]

Dalam kasus umum, kita mungkin memiliki fungsi \[ x \] yang memiliki \[ n \] parameter \[ p_1,\ldots,p_n \]. \[ f[x; p_1,\ldots,p_n] \]. Salah satu contohnya adalah $$ \begin{equation*} g[x; A, a] = Ae^{-ax} \thinspace. \end{equation*} $$

Bagaimana seharusnya kita mengimplementasikan fungsi seperti itu?

def y[t, v0]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[x, a, A]:
    return A*exp[-a*x]

Masalah

Ada satu masalah besar dengan solusi ini. Banyak perangkat lunak yang dapat kita gunakan untuk operasi matematika pada fungsi dengan asumsi bahwa fungsi dari satu variabel hanya memiliki satu argumen dalam representasi komputer dari fungsi tersebut. Misalnya, kita mungkin memiliki alat untuk membedakan fungsi \[ f[x] \] pada titik \[ x \], menggunakan pendekatan $$ \begin{equation} f'[x]\approx {f[x

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_

Fungsi

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
_1 bekerja dengan fungsi apa pun
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 yang membutuhkan satu argumen

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_

Sayangnya,

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
_1 tidak akan berfungsi dengan fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
4 kami. Memanggil
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
_5 menyebabkan kesalahan di dalam fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1, karena ia mencoba memanggil fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 kami hanya dengan satu argumen sedangkan fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 membutuhkan dua

Menulis fungsi

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 alternatif untuk
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 fungsi yang memiliki dua argumen adalah solusi yang buruk karena membatasi himpunan fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 yang dapat diterima untuk kasus yang sangat khusus dari suatu fungsi dengan satu variabel independen dan satu parameter. Prinsip dasar dalam pemrograman komputer adalah mengusahakan perangkat lunak yang dapat diterapkan secara umum dan seluas mungkin. Dalam kasus ini, itu berarti bahwa fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
_1 harus berlaku untuk semua fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 dari satu variabel, dan membiarkan
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 mengambil satu argumen maka keputusan alami untuk dibuat

Ketidaksesuaian argumen fungsi, seperti diuraikan di atas, merupakan masalah utama karena banyak pustaka perangkat lunak tersedia untuk operasi fungsi matematika dari satu variabel. integrasi, diferensiasi, penyelesaian \[ f[x]=0 \], menemukan ekstrem, dll. Semua pustaka ini akan mencoba memanggil fungsi matematika yang kami berikan hanya dengan satu argumen. Saat fungsi kita memiliki lebih banyak argumen, kode di dalam pustaka membatalkan panggilan ke fungsi kita, dan kesalahan semacam itu mungkin tidak selalu mudah dilacak

Solusi yang buruk. variabel global

Persyaratannya adalah untuk mendefinisikan implementasi Python dari fungsi matematika dari satu variabel dengan satu argumen, variabel independen. Kedua contoh di atas kemudian harus diimplementasikan sebagai

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]

Fungsi-fungsi ini hanya berfungsi jika

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5,
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
6, dan
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
7 adalah variabel global, diinisialisasi sebelum seseorang mencoba memanggil fungsi. Berikut adalah dua contoh panggilan di mana
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 membedakan
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 dan
def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]

Penggunaan variabel global secara umum dianggap pemrograman yang buruk. Mengapa variabel global bermasalah dalam kasus ini dapat diilustrasikan ketika ada kebutuhan untuk bekerja dengan beberapa versi fungsi. Misalkan kita ingin bekerja dengan dua versi \[ y[t;v_0] \], satu dengan \[ v_0=1 \] dan satu lagi dengan \[ v_0=5 \]. Setiap kali kita memanggil

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 kita harus mengingat versi fungsi mana yang kita gunakan, dan mengatur
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 sesuai sebelum panggilan

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]

Masalah lain adalah bahwa variabel dengan nama sederhana seperti

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5,
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
_7, dan
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
6 dapat dengan mudah digunakan sebagai variabel global di bagian lain dari program. Bagian ini dapat mengubah
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 kami dalam konteks yang berbeda dari fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, tetapi perubahan tersebut memengaruhi kebenaran fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7. Dalam kasus seperti itu, kami mengatakan bahwa mengubah
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 memiliki efek samping, yaitu. e. , perubahan memengaruhi bagian lain dari program dengan cara yang tidak disengaja. Inilah salah satu alasan mengapa aturan emas pemrograman memberi tahu kita untuk membatasi penggunaan variabel global sebanyak mungkin

Solusi lain untuk masalah kebutuhan dua \[ v_0 \] parameter bisa dengan memperkenalkan dua fungsi

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, masing-masing dengan parameter \[ v_0 \] yang berbeda

def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2

Sekarang kita perlu menginisialisasi

class Y:
    def __init__[self, v0]:
        self.v0 = v0
        self.g = 9.81

    def value[self, t]:
        return self.v0*t - 0.5*self.g*t**2
1 dan
class Y:
    def __init__[self, v0]:
        self.v0 = v0
        self.g = 9.81

    def value[self, t]:
        return self.v0*t - 0.5*self.g*t**2
2 sekali, dan kemudian kita dapat bekerja dengan
class Y:
    def __init__[self, v0]:
        self.v0 = v0
        self.g = 9.81

    def value[self, t]:
        return self.v0*t - 0.5*self.g*t**2
3 dan
class Y:
    def __init__[self, v0]:
        self.v0 = v0
        self.g = 9.81

    def value[self, t]:
        return self.v0*t - 0.5*self.g*t**2
4. Namun, jika kita membutuhkan 100 \[ v_0 \] parameter, kita membutuhkan 100 fungsi. Ini membosankan untuk kode, rawan kesalahan, sulit dikelola, dan hanya solusi yang sangat buruk untuk masalah pemrograman

Jadi, apakah ada obat yang bagus? . konsep kelas memecahkan semua masalah yang dijelaskan di atas

Mewakili fungsi sebagai kelas

Kelas berisi sekumpulan variabel [data] dan sekumpulan fungsi, yang disatukan sebagai satu unit. Variabel terlihat di semua fungsi di kelas. Artinya, kita dapat melihat variabel sebagai "global" dalam fungsi ini. Karakteristik ini juga berlaku untuk modul, dan modul dapat digunakan untuk mendapatkan banyak keuntungan yang sama seperti yang ditawarkan kelas [lihat komentar di bagian ]. Namun, kelas secara teknis sangat berbeda dari modul. Anda juga dapat membuat banyak salinan dari sebuah kelas, sementara hanya ada satu salinan dari sebuah modul. Ketika Anda menguasai modul dan kelas, Anda akan melihat dengan jelas persamaan dan perbedaannya. Sekarang kita lanjutkan dengan contoh spesifik dari sebuah kelas

Pertimbangkan fungsi \[ y[t; v_0]=v_0t - \frac{1}{2}gt^2 \]. Kita dapat mengatakan bahwa \[ v_0 \] dan \[ g \], diwakili oleh variabel

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dan
def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0, merupakan data. Fungsi Python, misalnya
class Y:
    def __init__[self, v0]:
        self.v0 = v0
        self.g = 9.81

    def value[self, t]:
        return self.v0*t - 0.5*self.g*t**2
_7, diperlukan untuk menghitung nilai \[ y[t;v_0] \] dan fungsi ini harus memiliki akses ke data
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dan
def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0, sementara
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
0 adalah argumen

Seorang programmer berpengalaman dengan kelas kemudian akan menyarankan untuk mengumpulkan data

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dan
def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0, dan fungsi
class Y:
    def __init__[self, v0]:
        self.v0 = v0
        self.g = 9.81

    def value[self, t]:
        return self.v0*t - 0.5*self.g*t**2
7, bersama-sama sebagai sebuah kelas. Selain itu, sebuah kelas biasanya memiliki fungsi lain yang disebut konstruktor untuk menginisialisasi data. Konstruktor selalu bernama
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4. Setiap kelas harus memiliki nama, seringkali dimulai dengan huruf besar, jadi kami memilih
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 sebagai nama karena kelas mewakili fungsi matematika dengan nama \[ y \]. Gambar sketsa isi kelas
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 sebagai apa yang disebut diagram UML, di sini dibuat dengan bantuan program class_Y_v1_UML. py. Diagram UML memiliki dua "kotak", satu tempat mencantumkan fungsi, dan satu lagi tempat mencantumkan variabel. Langkah kita selanjutnya adalah mengimplementasikan kelas ini dengan Python

Gambar 1. Diagram UML dengan fungsi dan data di kelas sederhana

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 untuk merepresentasikan fungsi matematika \[ y[t;v_0] \]

Penerapan

Kode lengkap untuk kelas kita

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 terlihat seperti berikut dengan Python

class Y:
    def __init__[self, v0]:
        self.v0 = v0
        self.g = 9.81

    def value[self, t]:
        return self.v0*t - 0.5*self.g*t**2

Kebingungan bagi pendatang baru di kelas Python adalah parameter

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 , yang mungkin memerlukan upaya dan waktu untuk memahami sepenuhnya

Penggunaan dan diseksi

Sebelum kita menggali apa arti setiap baris dalam implementasi kelas, kita mulai dengan menunjukkan bagaimana kelas dapat digunakan untuk menghitung nilai fungsi matematika \[ y[t;v_0] \]

Kelas membuat tipe data baru, di sini namanya

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5, jadi ketika kita menggunakan kelas untuk membuat objek, objek tersebut bertipe
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5. [Sebenarnya, semua objek Python standar, seperti daftar, tupel, string, angka titik-mengambang, bilangan bulat, dll. , adalah kelas Python bawaan, dengan nama
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
2,
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
3,
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4,
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5,
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
6, dll. ] Objek dari kelas yang ditentukan pengguna [seperti
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5] biasanya disebut instance. Kami membutuhkan contoh seperti itu untuk menggunakan data di kelas dan memanggil fungsi
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8. Pernyataan berikut membuat instance yang terikat pada nama variabel
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7

Tampaknya, kita memanggil kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 seolah-olah itu adalah sebuah fungsi. Sebenarnya,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_01 secara otomatis diterjemahkan oleh Python ke panggilan ke konstruktor
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4 di kelas
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5. Argumen dalam panggilan, di sini hanya nomor
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
04, selalu diteruskan sebagai argumen ke
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4 setelah argumen
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9. Artinya,
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
_5 mendapatkan nilai
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
04 dan
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 baru saja dijatuhkan dalam panggilan. Ini mungkin membingungkan, tetapi merupakan aturan bahwa argumen
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 tidak pernah digunakan dalam pemanggilan fungsi di kelas

Dengan contoh

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, kita dapat menghitung nilai \[ y[t=0. 1;v_0=3] \] dengan pernyataan

Di sini juga, argumen

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9 dijatuhkan dalam panggilan ke
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8. Untuk mengakses fungsi dan variabel di kelas, kita harus mengawali nama fungsi dan variabel dengan nama instance dan titik. fungsi
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_8 dicapai sebagai
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
15, dan variabel dicapai sebagai
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
16 dan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
17. Kita dapat, misalnya, mencetak nilai
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dalam contoh
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 dengan menulis

Keluaran dalam hal ini adalah

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_04

Kami telah memperkenalkan istilah "contoh" untuk objek kelas. Fungsi dalam kelas biasa disebut metode, dan variabel [data] dalam kelas disebut atribut data. Metode juga dikenal sebagai atribut metode. Mulai sekarang kita akan menggunakan terminologi ini. Di kelas sampel kami

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 kami memiliki dua metode atau atribut metode,
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4 dan
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8, dua atribut data,
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dan
def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0, dan total empat atribut [
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4,
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8,
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5, dan _______. Nama atribut dapat dipilih secara bebas, sama seperti nama fungsi dan variabel Python biasa. Namun, konstruktor harus memiliki nama
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4, jika tidak maka konstruktor tidak akan dipanggil secara otomatis saat kita membuat instance baru

Anda dapat melakukan apa pun yang Anda inginkan dalam metode apa pun, tetapi merupakan konvensi umum untuk menggunakan konstruktor untuk menginisialisasi variabel di kelas

Perpanjangan kelas

Kita dapat memiliki atribut sebanyak yang kita suka di kelas, jadi mari kita tambahkan metode baru ke kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5. Metode ini disebut
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
32 dan mencetak string yang berisi rumus fungsi matematika \[ y \]. Setelah rumus ini, kami memberikan nilai \[ v_0 \]. String kemudian dapat dibangun sebagai

'v0*t - 0.5*g*t**2; v0=%g' % self.v0

di mana

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9 adalah turunan dari kelas
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5. Panggilan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_32 tidak memerlukan argumen apa pun

harus cukup untuk membuat, mengembalikan, dan mencetak string. Namun, meskipun metode

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_32 tidak memerlukan argumen apa pun, ia harus memiliki argumen
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9, yang tidak disertakan dalam panggilan tetapi diperlukan di dalam metode untuk mengakses atribut. Oleh karena itu penerapan metode ini

    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0

Untuk kelengkapan, seluruh kelas sekarang membaca

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_0

Contoh penggunaan mungkin

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_1

dengan keluaran

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_2

Hati-hati dengan lekukan dalam pemrograman kelas. Kesalahan umum yang dilakukan oleh pendatang baru dalam konstruksi kelas adalah menempatkan kode yang menerapkan kelas pada indentasi yang sama dengan metode kelas. Ini ilegal. Hanya definisi metode dan penugasan untuk apa yang disebut atribut data statis [bagian ] yang dapat muncul di blok indentasi di bawah judul

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
38. Penugasan atribut data biasa harus dilakukan di dalam metode. Program utama yang menggunakan kelas harus muncul dengan indentasi yang sama dengan judul
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
38

Menggunakan metode sebagai fungsi biasa

Kita dapat membuat beberapa fungsi \[ y \] dengan nilai \[ v_0 \] yang berbeda

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_3

Kita dapat memperlakukan

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
40,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
41, dan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
42 sebagai fungsi Python biasa dari
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
0, lalu meneruskannya ke fungsi Python apa pun yang mengharapkan fungsi dari satu variabel. Secara khusus, kami dapat mengirim fungsi ke fungsi
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
44 dari bagian tersebut

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_4

Di dalam fungsi

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_44, argumen
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 sekarang berperilaku sebagai fungsi dari satu variabel yang secara otomatis membawa serta dua variabel
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dan
def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0. Ketika
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
_2 mengacu pada [mis. g. ]
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_42, Python benar-benar tahu bahwa
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
51 berarti
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
52, dan di dalam
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
42 metode
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 adalah
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
55, dan kami memiliki akses ke
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
56 dan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
57

Kelas gaya baru versus kelas klasik

Saat menggunakan Python versi 2 dan menulis kelas seperti

kita mendapatkan apa yang dikenal sebagai kelas gaya lama atau klasik. Implementasi kelas yang direvisi dalam Python datang dalam versi 2. 2 dengan kelas gaya baru. Spesifikasi kelas gaya baru membutuhkan

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
58 setelah nama kelas

Kelas gaya baru memiliki lebih banyak fungsi, dan secara umum disarankan untuk bekerja dengan kelas gaya baru. Oleh karena itu, mulai sekarang kami akan menulis

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_59 daripada hanya
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
60. Di Python 3, semua kelas adalah gaya baru apakah kita menulis
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
60 atau
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
59

String dokumen

Suatu fungsi mungkin memiliki string dokumen tepat setelah definisi fungsi, lihat bagian ref{detik. dasar. dokumen}. Tujuan dari string doc adalah untuk menjelaskan tujuan dari fungsi dan, misalnya, apa argumen dan nilai kembaliannya. Kelas juga dapat memiliki string dokumen, ini hanya string pertama yang muncul tepat setelah judul

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
38. Konvensinya adalah untuk menyertakan string doc dalam tanda kutip rangkap tiga
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
64

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_5

Informasi yang lebih komprehensif dapat mencakup metode dan bagaimana kelas digunakan dalam sesi interaktif

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_6

Variabel diri

Sekarang kami akan memberikan penjelasan lebih lanjut tentang parameter

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 dan cara kerja metode kelas. Di dalam konstruktor
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
4, argumen
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 adalah variabel yang menampung instance baru yang akan dibangun. Ketika kita menulis

kami mendefinisikan dua atribut data baru dalam contoh ini. Parameter

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9 secara tidak terlihat dikembalikan ke kode panggilan. Kita dapat membayangkan bahwa Python menerjemahkan sintaks
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
69 menjadi panggilan yang ditulis sebagai

Sekarang,

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9 menjadi instance baru
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 yang ingin kita buat, jadi ketika kita melakukan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
72 di konstruktor, kita benar-benar menetapkan
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 ke
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
16. Awalan dengan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
75 mengilustrasikan cara mencapai metode kelas dengan sintaks yang mirip dengan mencapai fungsi dalam modul [seperti
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
76]. Jika kita awali dengan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
75, kita perlu memberi makan secara eksplisit dalam contoh untuk argumen
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9, seperti
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 pada baris kode di atas, tetapi jika kita awali dengan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
80 [nama contoh] argumen
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 dijatuhkan dalam sintaks, dan Python akan . Ini adalah "awalan nama instance" terakhir yang akan kita gunakan saat menghitung dengan kelas. [
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
84 tidak akan berfungsi karena
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 tidak ditentukan dan seharusnya menjadi objek
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5. Namun, jika pertama-tama kita membuat
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_87 lalu memanggil
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
84, sintaks berfungsi, dan
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
16 adalah
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
04 setelah panggilan. ]

Mari kita lihat panggilan ke metode

    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8 untuk melihat penggunaan serupa dari argumen
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9. Ketika kita menulis

Python menerjemahkan ini menjadi panggilan

sehingga argumen

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 dalam metode
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8 menjadi instance
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7. Dalam ekspresi di dalam metode
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_8,

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_7

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9 adalah
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 jadi ini sama dengan

Penggunaan

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9 mungkin menjadi lebih jelas ketika kita memiliki banyak instance kelas. Kita dapat membuat kelas yang hanya memiliki satu parameter sehingga kita dapat dengan mudah mengidentifikasi instance kelas dengan mencetak nilai parameter ini. Selain itu, setiap objek Python
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_00 memiliki pengidentifikasi unik yang diperoleh oleh
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
01 yang juga dapat kita cetak untuk melacak apa
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 itu

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_8

Berikut adalah sesi interaktif dengan kelas ini

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
_9

Kami melihat dengan jelas bahwa

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9 di dalam konstruktor adalah objek yang sama dengan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
04, yang ingin kami buat dengan memanggil konstruktor

Objek kedua dibuat oleh

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_0

Sekarang kita dapat memanggil metode

    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8 menggunakan sintaks standar
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
06 dan sintaks "lebih pedagogis"
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
07. Menggunakan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
04 dan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
09 mengilustrasikan bagaimana
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 mengambil nilai yang berbeda, sementara kita dapat melihat metode
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
11 sebagai fungsi tunggal yang hanya beroperasi pada objek
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 dan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
13 yang berbeda

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_1

Semoga ilustrasi ini membantu menjelaskan bahwa

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 hanyalah contoh yang digunakan dalam awalan pemanggilan metode, di sini
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
04 atau
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
09. Jika tidak, pasien bekerja dengan pemrograman kelas dengan Python dari waktu ke waktu akan mengungkapkan pemahaman tentang apa sebenarnya
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 itu

Aturan tentang

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_9
  • Setiap metode kelas harus memiliki
    'v0*t - 0.5*g*t**2; v0=%g' % self.v0
    
    _9 sebagai argumen pertama. [Nama dapat berupa nama variabel yang valid, tetapi nama
    'v0*t - 0.5*g*t**2; v0=%g' % self.v0
    
    9 adalah konvensi yang sudah mapan di Python. ]
  • 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
    
    _9 mewakili instance [sewenang-wenang] dari kelas
  • Untuk mengakses atribut kelas apa pun di dalam metode kelas, kita harus diawali dengan
    'v0*t - 0.5*g*t**2; v0=%g' % self.v0
    
    9, seperti pada
    def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    23, di mana
    def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    24 adalah nama atribut
  • 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
    
    _9 dijatuhkan sebagai argumen dalam panggilan ke metode kelas

Contoh kelas fungsi lainnya

Mari kita terapkan ide dari kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_5 ke fungsi $$ \begin{equation*} v[r] = \left[{\beta\over 2\mu_0}\right]^{{1/ n}} {n . Kami dapat menulis fungsi ini sebagai \[ v[r; \beta,\mu_0,n,R] \] untuk secara eksplisit menunjukkan bahwa ada satu variabel independen primer [\[ r \]] dan empat parameter fisik \[ \beta \ . Kelas biasanya menyimpan parameter fisik sebagai variabel dan menyediakan metode
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
27 untuk menghitung fungsi \[ v \]

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_2

Tampaknya ada satu hal baru di sini yaitu kami menginisialisasi beberapa variabel pada baris yang sama

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_3

Daftar variabel yang dipisahkan koma di sisi kanan membentuk sebuah tupel sehingga penugasan ini hanyalah konstruksi yang valid di mana sekumpulan variabel di sisi kiri diatur sama dengan daftar atau tupel di sisi kanan . Kode multi-baris yang setara adalah

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_4

Dalam metode

    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8 lebih mudah untuk menghindari awalan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
29 dalam rumus matematika dan memperkenalkan nama pendek lokal
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
30,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
31,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
32, dan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
33. Ini secara umum merupakan ide yang bagus, karena memudahkan untuk membaca implementasi rumus dan memeriksa kebenarannya

Komentar

Solusi lain untuk masalah mengirim fungsi dengan parameter ke fungsi perpustakaan umum seperti

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 disediakan dalam dokumen Jumlah variabel argumen fungsi dengan Python. Obatnya adalah mentransfer parameter sebagai argumen "melalui" fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1. Hal ini dapat dilakukan secara umum seperti yang dijelaskan pada lampiran tersebut

Implementasi kelas fungsi alternatif

Untuk mengilustrasikan pemrograman kelas lebih lanjut, sekarang kita akan menyadari kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 dari bagian dengan cara yang berbeda. Anda dapat menganggap bagian ini sebagai lanjutan dan melewatinya, tetapi bagi beberapa pembaca materi tersebut mungkin meningkatkan pemahaman kelas
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 dan memberikan beberapa wawasan tentang pemrograman kelas secara umum

Merupakan kebiasaan yang baik untuk selalu memiliki konstruktor di kelas dan menginisialisasi atribut data di kelas di sini, tetapi ini bukan persyaratan. Mari kita tinggalkan konstruktor dan menjadikan

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 argumen opsional untuk metode
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8. Jika pengguna tidak memberikan
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
_5 dalam panggilan ke
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8, kami menggunakan nilai
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 yang harus diberikan dalam panggilan sebelumnya dan disimpan sebagai atribut data
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43. Kami dapat mengenali apakah pengguna memberikan
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
_5 sebagai argumen atau tidak dengan menggunakan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
45 sebagai nilai default untuk argumen kata kunci dan kemudian menguji apakah
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
46

Implementasi alternatif kami dari kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_5, bernama
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48, sekarang berbunyi

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_5

Kali ini kelas hanya memiliki satu metode dan satu atribut data saat kita melewatkan konstruktor dan membiarkan

def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0 menjadi variabel lokal dalam metode
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8

Tetapi jika tidak ada konstruktor, bagaimana sebuah instance dibuat? . Ini memungkinkan kita untuk menulis

untuk membuat contoh

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
_7. Karena tidak ada yang terjadi pada konstruktor kosong yang dihasilkan secara otomatis,
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 tidak memiliki atribut data pada tahap ini. Menulis

sehingga mengarah pada pengecualian

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_6

Dengan menyebut

kami membuat atribut

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43 di dalam metode
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8. Secara umum, kita dapat membuat atribut apa pun
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
24 dengan metode apa pun hanya dengan memberikan nilai ke
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
23. Sekarang mencoba a

akan mencetak

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_57. Dalam panggilan baru,

nilai

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
_5 sebelumnya [
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
57] digunakan di dalam
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8 sebagai
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43 kecuali argumen
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 ditentukan dalam panggilan

Implementasi sebelumnya tidak aman jika kita gagal menginisialisasi

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5. Misalnya, kode

akan berakhir dengan metode

    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_8 dengan pengecualian

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_6

Seperti biasa, lebih baik memberi tahu pengguna dengan pesan yang lebih informatif. Untuk memeriksa apakah kita memiliki atribut

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
_5, kita dapat menggunakan fungsi Python
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
66. Memanggil
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_67 mengembalikan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
68 hanya jika instance
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 memiliki atribut dengan nama
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
70. Metode
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8 yang ditingkatkan sekarang terbaca

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_8

Sebagai alternatif, kita dapat mencoba mengakses

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_43 dalam blok
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
73, dan mungkin mengajukan pengecualian
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
74 [yang dimunculkan oleh Python jika tidak ada cukup argumen untuk suatu fungsi atau metode]

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_9

Perhatikan bahwa Python mendeteksi

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
_75, tetapi dari sudut pandang pengguna, tidak cukup parameter yang diberikan dalam panggilan sehingga
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
74 lebih tepat untuk berkomunikasi kembali ke kode panggilan

Menurut kami kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5 adalah implementasi yang lebih baik daripada kelas
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48, karena yang pertama lebih sederhana. Seperti yang telah disebutkan, adalah kebiasaan yang baik untuk memasukkan konstruktor dan mengatur data di sini daripada "merekam data dengan cepat" seperti yang kami coba di kelas
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48. Seluruh tujuan kelas
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48 hanya untuk menunjukkan bahwa Python memberikan fleksibilitas yang besar sehubungan dengan mendefinisikan atribut, dan bahwa tidak ada persyaratan untuk apa yang harus dimiliki oleh suatu kelas.

Membuat kelas tanpa konstruksi kelas

Pendatang baru di konsep kelas sering kali kesulitan memahami tentang apa konsep ini. Bagian ini mencoba untuk menjelaskan secara lebih rinci bagaimana kita dapat memperkenalkan kelas tanpa konstruksi kelas dalam bahasa komputer. Informasi ini mungkin atau mungkin tidak meningkatkan pemahaman Anda tentang kelas. Jika tidak, pemrograman dengan kelas pasti akan meningkatkan pemahaman Anda seiring berjalannya waktu, jadi tidak ada alasan untuk khawatir. Bahkan, Anda dapat dengan aman melompat ke bagian karena tidak ada konsep penting di bagian ini yang dibangun di bagian selanjutnya

Kelas berisi kumpulan variabel [data] dan kumpulan metode [fungsi]. Kumpulan variabel unik untuk setiap instance kelas. Artinya, jika kita membuat sepuluh instance, masing-masing memiliki kumpulan variabelnya sendiri. Variabel ini dapat dianggap sebagai kamus dengan kunci yang sama dengan nama variabel. Setiap instance kemudian memiliki kamusnya sendiri, dan kami dapat secara kasar melihat instance sebagai kamus ini. [Instance juga dapat berisi atribut data statis [bagian ], tetapi ini harus dilihat sebagai variabel global dalam konteks saat ini. ]

Di sisi lain, metode dibagikan di antara instance. Kita mungkin menganggap metode di kelas sebagai fungsi global standar yang menggunakan instance dalam bentuk kamus sebagai argumen pertama. Metode kemudian memiliki akses ke variabel dalam contoh [kamus] yang disediakan dalam panggilan. Untuk kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_5 dari bagian dan instance
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, metodenya adalah fungsi biasa dengan nama dan argumen berikut

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
0

Kelas bertindak sebagai namespace, artinya semua fungsi harus diawali dengan nama namespace, di sini

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5. Dua kelas yang berbeda, katakanlah
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
84 dan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
85, mungkin memiliki fungsi dengan nama yang sama, katakanlah
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8, tetapi ketika
    def formula[self]:
        return 'v0*t - 0.5*g*t**2; v0=%g' % self.v0
8 fungsi milik ruang nama yang berbeda, namanya
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
88 dan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
89 menjadi berbeda. Modul juga merupakan ruang nama untuk fungsi dan variabel di dalamnya [pikirkan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
90,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
91,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
92]

Satu-satunya hal yang aneh dengan konstruksi kelas di Python adalah memungkinkan kita untuk menggunakan sintaks alternatif untuk pemanggilan metode

Sintaks ini bertepatan dengan sintaks tradisional pemanggilan metode kelas dan memberikan argumen, seperti yang ditemukan dalam bahasa komputer lainnya, seperti Java, C#, C++, Simula, dan Smalltalk. Notasi titik juga digunakan untuk mengakses variabel dalam contoh sehingga kita di dalam metode dapat menulis

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43 alih-alih
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
94 [
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
9 merujuk ke
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 melalui pemanggilan fungsi]

Kita dapat dengan mudah mengimplementasikan versi sederhana dari konsep kelas tanpa konstruksi kelas dalam bahasa. Yang kita butuhkan hanyalah tipe kamus dan fungsi biasa. Kamus bertindak sebagai instance, dan metode adalah fungsi yang mengambil kamus ini sebagai argumen pertama sehingga fungsi tersebut memiliki akses ke semua variabel dalam instance. Kelas

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
_5 kita sekarang dapat diimplementasikan sebagai

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
1

Kedua fungsi tersebut ditempatkan dalam sebuah modul bernama

'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5. Penggunaannya sebagai berikut

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
2

Kami tidak memiliki konstruktor karena inisialisasi variabel dilakukan saat mendeklarasikan kamus

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, tetapi kami juga dapat menyertakan beberapa fungsi inisialisasi dalam modul
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
3

Penggunaannya sekarang sedikit berbeda

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
_4

Cara mengimplementasikan kelas dengan bantuan kamus dan sekumpulan fungsi biasa ini sebenarnya membentuk dasar implementasi kelas dalam banyak bahasa. Python dan Perl bahkan memiliki sintaks yang mendemonstrasikan jenis implementasi ini. Bahkan, setiap instance kelas di Python memiliki kamus

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
01 sebagai atribut, yang menampung semua variabel dalam instance. Berikut adalah demo yang membuktikan keberadaan kamus ini di kelas
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
5

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
5

Untuk meringkas. Kelas Python dapat dianggap sebagai beberapa variabel yang dikumpulkan dalam kamus, dan sekumpulan fungsi di mana kamus ini secara otomatis disediakan sebagai argumen pertama sehingga fungsi selalu memiliki akses penuh ke variabel kelas

Komentar pertama

Kami telah di bagian ini memberikan pandangan tentang kelas dari sudut pandang teknis. Orang lain mungkin melihat kelas sebagai cara memodelkan dunia dalam hal data dan operasi pada data. Namun, dalam ilmu yang menggunakan bahasa matematika, pemodelan dunia biasanya dilakukan dengan matematika, dan struktur matematika memberikan pemahaman tentang masalah dan struktur program. Bila sesuai, struktur matematika dapat dengan mudah dipetakan ke kelas dalam program untuk membuat perangkat lunak lebih sederhana dan lebih fleksibel

Komentar kedua

Tampilan kelas di bagian ini mengabaikan topik yang sangat penting seperti pewarisan dan pengikatan dinamis [dijelaskan dalam dokumen Pemrograman berorientasi objek ]. Untuk kelengkapan lebih lanjut dari bagian ini, oleh karena itu kami menjelaskan secara singkat bagaimana kombinasi kamus dan fungsi global kami dapat menangani pewarisan dan pengikatan dinamis [tetapi ini tidak masuk akal kecuali Anda tahu apa itu pewarisan]

Pewarisan data dapat diperoleh dengan membiarkan kamus subkelas melakukan panggilan

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
03 dengan kamus superkelas sebagai argumen. Dengan cara ini semua data di superclass juga tersedia di kamus subclass. Pengikatan dinamis metode lebih rumit, tetapi seseorang dapat berpikir untuk memeriksa apakah metode tersebut ada dalam modul subkelas [menggunakan
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
66], dan jika tidak, seseorang melanjutkan dengan memeriksa modul kelas super hingga versi metode ditemukan

Penutupan

Bagian ini menindaklanjuti diskusi di bagian ini dan menyajikan konstruksi yang lebih maju yang dapat berfungsi sebagai alternatif konstruksi kelas dalam beberapa kasus

Contoh motivasi kami adalah bahwa kami ingin implementasi Python dari fungsi matematika \[ y[t;v_0]=v_0t - \frac{1}{2}gt^2 \] memiliki \[ t \] sebagai satu-satunya argumen, . Pertimbangkan fungsi berikut, yang mengembalikan fungsi

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
6

Properti luar biasa dari fungsi

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 adalah ia mengingat nilai
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dan
def y1[t]:
    g = 9.81
    return v0_1*t - 0.5*g*t**2

def y2[t]:
    g = 9.81
    return v0_2*t - 0.5*g*t**2
0, meskipun variabel ini tidak lokal untuk fungsi induk
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
08 dan bukan lokal di
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7. Secara khusus, kita dapat menentukan
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 sebagai argumen untuk
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
08

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
7

Di sini,

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
_12 memiliki akses ke
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
13 sementara
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
14 memiliki akses ke
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
15

Fungsi

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
_16 yang kita buat dan kembalikan dari
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
08 disebut penutupan dan mengingat nilai variabel lokal di sekitarnya dalam fungsi induk [pada saat kita membuat fungsi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7]. Penutupan sangat nyaman untuk banyak tujuan dalam komputasi matematika. Contoh muncul di bagian. Penutupan juga penting dalam gaya pemrograman yang disebut pemrograman fungsional

Menghasilkan banyak penutupan dalam suatu fungsi. Segera setelah Anda mendapatkan ide penutupan, Anda mungkin akan sering menggunakannya karena ini adalah cara mudah untuk mengemas fungsi dengan data tambahan. Namun, ada beberapa jebakan. Yang terbesar diilustrasikan di bawah ini, tetapi ini dianggap materi tingkat lanjut

Mari kita buat serangkaian fungsi

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
_19 untuk berbagai nilai parameter
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5. Setiap fungsi hanya mengembalikan tuple
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
21 sehingga kita dapat dengan mudah melihat apa argumen dan parameternya. Kami menggunakan
def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
_22 untuk mendefinisikan setiap fungsi dengan cepat, dan kami menempatkan fungsi dalam daftar

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
8

Sekarang,

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
_23 adalah daftar fungsi dengan satu argumen. Memanggil setiap fungsi dan mencetak nilai pengembalian
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 dan
'v0*t - 0.5*g*t**2; v0=%g' % self.v0
0 memberikan

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
_9

Seperti yang kita lihat, semua fungsi memiliki

def y[t]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[t]:
    return A*exp[-a*x]
26, i. e. , mereka menyimpan nilai terbaru
v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
5 sebelum dikembalikan. Ini bukan yang kami inginkan

Triknya adalah membiarkan

v0 = 1; r1 = y[t]
v0 = 5; r2 = y[t]
_5 menjadi argumen kata kunci di setiap fungsi, karena nilai argumen kata kunci dibekukan pada saat fungsi didefinisikan

Bagaimana Anda mengakses variabel dari fungsi lain di Python?

Variabel dapat ditetapkan ke objek fungsi di dalam badan fungsi . Jadi variabel hanya ada setelah fungsi dipanggil. Setelah fungsi dipanggil, variabel akan dikaitkan dengan objek fungsi.

Bagaimana Anda mengakses variabel dari satu metode dalam metode lain dari kelas yang sama dengan Python?

Anda melakukan ini dengan menetapkan atribut dari parameter self ke fungsi. Simpan jawaban ini

Bagaimana cara mengakses variabel satu metode dari metode lain dalam kelas Java yang sama?

dan karena metode utama statis maka variabel juga statis. dan jika itu adalah variabel global statis, itu dapat diakses dari metode apa pun di kelas yang sama menggunakan className. .
Tes kelas publik {
int statis x;
public static void main[] {
x = 100;
Sistem. keluar. cetak[x];
publik int getx[] {
kembali x;

Bisakah Anda memanggil variabel dari fungsi lain dengan Python?

Dalam Python dan sebagian besar bahasa pemrograman, variabel yang dideklarasikan di luar fungsi dikenal sebagai variabel global. Anda dapat mengakses variabel tersebut di dalam dan di luar fungsi, karena memiliki cakupan global .

Bài mới nhất

Chủ Đề