Saya mengalami kesalahan metode tidak terikat di python dengan kode
import random
class Sample(object):
'''This class defines various methods related to the sample'''
def drawSample(samplesize,List):
sample=random.sample(List,samplesize)
return sample
Choices=range(100)
print Sample.drawSample(5,Choices)
Setelah membaca banyak posting bermanfaat di sini, saya memikirkan bagaimana saya bisa menambahkan di @staticmethod
atas agar kode berfungsi. Saya seorang pemula python. Adakah yang bisa menjelaskan mengapa seseorang ingin mendefinisikan metode statis? Atau, mengapa tidak semua metode didefinisikan sebagai metode statis?
python
oop
static-methods
Curious2learn
sumber
sumber
Jawaban:
Metode statis memiliki penggunaan yang terbatas, karena mereka tidak memiliki akses ke atribut instance kelas (seperti metode biasa), dan tidak memiliki akses ke atribut kelas itu sendiri (seperti metode kelas. ).
Jadi mereka tidak berguna untuk metode sehari-hari.
Namun, mereka dapat berguna untuk mengelompokkan beberapa fungsi utilitas bersama dengan sebuah kelas - misalnya konversi sederhana dari satu jenis ke jenis lainnya - yang tidak memerlukan akses ke informasi apa pun selain dari parameter yang disediakan (dan mungkin beberapa atribut global ke modul. )
Mereka dapat ditempatkan di luar kelas, tetapi mengelompokkan mereka di dalam kelas mungkin masuk akal jika hanya diterapkan di sana.
Anda juga dapat mereferensikan metode melalui sebuah instance atau kelas, daripada nama modul, yang dapat membantu pembaca memahami instance apa yang terkait dengan metode tersebut.
sumber
Locale
kelas contoh , yang instansinya akan menjadi lokal (duh). SebuahgetAvailableLocales()
metode akan menjadi contoh yang bagus dari metode statis kelas tersebut: itu jelas milik kelas Lokal, sementara juga jelas bukan milik contoh tertentu.class_name.attribute
, just notcls.attribute
orself.attribute
. Ini berlaku untuk atribut "publik". Sesuai ketentuan, Anda tidak boleh mengakses atribut yang disembunyikan dengan garis bawah, atau nama yang tercabik-cabik dengan dua garis bawah, dengan cara ini. Ini juga berarti kode Anda akan lebih rapuh ketika atribut berpindah tempat pada hierarki pewarisan.Lihat artikel ini untuk penjelasan rinci.
TL; DR
1. Ini menghilangkan penggunaan
self
argumen.2. Ini mengurangi penggunaan memori karena Python tidak harus membuat contoh metode terikat untuk setiap objek yang diinstiansi:
>>>RandomClass().regular_method is RandomClass().regular_method False >>>RandomClass().static_method is RandomClass().static_method True >>>RandomClass.static_method is RandomClass().static_method True
3. Ini meningkatkan keterbacaan kode, menandakan bahwa metode tersebut tidak bergantung pada status objek itu sendiri.
4. Hal ini memungkinkan untuk metode overriding jika metode didefinisikan pada tingkat modul (yaitu di luar kelas) subkelas tidak akan dapat menggantikan metode itu.
sumber
Ini tidak tepat pada pertanyaan Anda yang sebenarnya, tetapi karena Anda telah mengatakan bahwa Anda adalah pemula python mungkin itu akan membantu, dan tidak ada orang lain yang cukup keluar dan mengatakannya secara eksplisit.
Saya tidak akan pernah memperbaiki kode di atas dengan membuat metode metode statis. Saya akan meninggalkan kelas dan hanya menulis fungsi:
def drawSample(samplesize,List): sample=random.sample(List,samplesize) return sample Choices=range(100) print drawSample(5,Choices)
Jika Anda memiliki banyak fungsi terkait, Anda dapat mengelompokkannya dalam sebuah modul - yaitu, taruh semuanya dalam file yang sama, dinamai
sample.py
misalnya; kemudianimport sample Choices=range(100) print sample.drawSample(5,Choices)
Atau saya akan menambahkan
__init__
metode ke kelas dan membuat contoh yang memiliki metode yang berguna:class Sample(object): '''This class defines various methods related to the sample''' def __init__(self, thelist): self.list = thelist def draw_sample(self, samplesize): sample=random.sample(self.list,samplesize) return sample choices=Sample(range(100)) print choices.draw_sample(5)
(Saya juga mengubah konvensi case pada contoh di atas agar sesuai dengan gaya yang direkomendasikan oleh PEP 8.)
Salah satu kelebihan Python adalah tidak memaksa Anda menggunakan kelas untuk semuanya. Anda dapat menggunakannya hanya jika ada data atau status yang harus dikaitkan dengan metode, untuk tujuan kelas apa. Jika tidak, Anda dapat menggunakan fungsi, untuk apa fungsi itu.
sumber
Mengapa seseorang ingin mendefinisikan metode statis ?
Misalkan kita memiliki
class
disebutMath
kemudiantak seorang pun ingin membuat objek
class Math
dan kemudian memanggil metode seperti
ceil
danfloor
danfabs
di atasnya.Jadi kami membuatnya
static
.Misalnya melakukan
>> Math.floor(3.14)
jauh lebih baik daripada
>> mymath = Math() >> mymath.floor(3.14)
Jadi mereka berguna dalam beberapa hal. Anda tidak perlu membuat instance kelas untuk menggunakannya.
Mengapa tidak semua metode didefinisikan sebagai metode statis ?
Mereka tidak memiliki akses ke variabel instance.
class Foo(object): def __init__(self): self.bar = 'bar' def too(self): print self.bar @staticmethod def foo(): print self.bar Foo().too() # works Foo.foo() # doesn't work
Itulah mengapa kami tidak membuat semua metode menjadi statis.
sumber
Math
. Itulah mengapa saya menggunakan huruf besarM
.Math
menjadi kelas sejak awal, modul akan lebih cocok. Cobalah untuk menemukan contoh kelas yang masuk akal sebagai kelas, bukan kelas yang "tak seorang pun ingin membuat objek" .Saat Anda memanggil objek fungsi dari instance objek, itu menjadi 'metode terikat' dan objek instance itu sendiri diteruskan sebagai argumen pertama.
Saat Anda memanggil sebuah
classmethod
objek (yang membungkus sebuah objek fungsi) pada sebuah instance objek, kelas dari objek instance tersebut dilewatkan sebagai argumen pertama.Saat Anda memanggil
staticmethod
objek (yang membungkus objek fungsi), tidak ada argumen pertama implisit yang digunakan.class Foo(object): def bar(*args): print args @classmethod def baaz(*args): print args @staticmethod def quux(*args): print args >>> foo = Foo() >>> Foo.bar(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unbound method bar() must be called with Foo instance as first argument (got int instance instead) >>> Foo.baaz(1,2,3) (<class 'Foo'>, 1, 2, 3) >>> Foo.quux(1,2,3) (1, 2, 3) >>> foo.bar(1,2,3) (<Foo object at 0x1004a4510>, 1, 2, 3) >>> foo.baaz(1,2,3) (<class 'Foo'>, 1, 2, 3) >>> foo.quux(1,2,3) (1, 2, 3)
sumber
metode statis sangat bagus karena Anda tidak perlu mendeklarasikan instance objek tempat metode tersebut berada.
Situs python memiliki beberapa dokumentasi bagus tentang metode statis di sini:
http://docs.python.org/library/functions.html#staticmethod
sumber
Alternatif untuk
staticmethod
adalah:classmethod
,instancemethod
, danfunction
. Jika Anda tidak tahu apa ini, gulir ke bawah ke bagian terakhir. Jika astaticmethod
lebih baik daripada salah satu alternatif ini, tergantung pada tujuan penulisannya.keuntungan dari metode statis Python
staticmethod
lebih baik daripada aclassmethod
atauinstancemethod
. Dengan begitu jelas (dari@staticmethod
dekorator) bahwa status kelas dan instance tidak dibaca atau diubah. Namun, menggunakan afunction
membuat perbedaan itu lebih jelas (lihat kerugian).staticmethod
sama dengan tanda tangan aclassmethod
atauinstancemethod
, yaitu<instance>.<method>(<arguments>)
. Oleh karena itu dapat dengan mudah diganti dengan salah satu dari tiga jika itu diperlukan nanti atau di kelas turunan. Anda tidak dapat melakukannya dengan sederhanafunction
.staticmethod
dapat digunakan sebagai pengganti afunction
untuk memperjelas bahwa itu secara subjektif milik kelas dan untuk mencegah konflik namespace.kerugian dari metode statis Python
staticmethod
sama dengan tanda tanganclassmethod
atauinstancemethod
. Ini menutupi fakta bahwastaticmethod
sebenarnya tidak membaca atau mengubah informasi objek apa pun. Ini membuat kode lebih sulit untuk dibaca. Mengapa tidak menggunakan afunction
?staticmethod
sulit digunakan kembali jika Anda perlu memanggilnya dari luar kelas / instance tempat ia didefinisikan. Jika ada potensi untuk digunakan kembali, afunction
adalah pilihan yang lebih baik.staticmethod
jarang digunakan, jadi orang yang membaca kode yang menyertakannya mungkin membutuhkan waktu lebih lama untuk membacanya.alternatif untuk metode statis dengan Python
Untuk membahas tentang keuntungan dari
staticmethod
, kita perlu mengetahui apa alternatif itu dan bagaimana perbedaannya satu sama lain.staticmethod
milik kelas tetapi tidak dapat mengakses atau mengubah setiap contoh atau kelas informasi.Ada tiga alternatif untuk itu:
classmethod
memiliki akses ke kelas pemanggil.instancemethod
memiliki akses ke contoh pemanggil dan kelasnya.function
ada hubungannya dengan kelas. Ini adalah yang paling dekat dalam kapabilitas denganstaticmethod
.Inilah yang terlihat seperti dalam kode:
# function # has nothing to do with a class def make_cat_noise(asker_name): print('Hi %s, mieets mieets!' % asker_name) # Yey, we can make cat noises before we've even defined what a cat is! make_cat_noise('JOey') # just a function class Cat: number_of_legs = 4 # special instance method __init__ def __init__(self, name): self.name = name # instancemethod # the instance (e.g. Cat('Kitty')) is passed as the first method argument def tell_me_about_this_animal(self, asker_name): print('Hi %s, This cat has %d legs and is called %s' % (asker_name, self.number_of_legs, self.name)) # classmethod # the class (e.g. Cat) is passed as the first method argument # by convention we call that argument cls @classmethod def tell_me_about_cats(cls, asker_name): print("Hi %s, cats have %d legs." % (asker_name, cls.number_of_legs)) # cls.name # AttributeError because only the instance has .name # self.name # NameError because self isn't defined in this namespace # staticmethod # no information about the class or the instance is passed to the method @staticmethod def make_noise(asker_name): print('Hi %s, meooow!' % asker_name) # class and instance are not accessible from here # one more time for fun! make_cat_noise('JOey') # just a function # We just need the class to call a classmethod or staticmethod: Cat.make_noise('JOey') # staticmethod Cat.tell_me_about_cats('JOey') # classmethod # Cat.tell_me_about_this_animal('JOey') # instancemethod -> TypeError # With an instance we can use instancemethod, classmethod or staticmethod mycat = Cat('Kitty') # mycat is an instance of the class Cat mycat.make_noise('JOey') # staticmethod mycat.tell_me_about_cats('JOey') # classmethod mycat.tell_me_about_this_animal('JOey') # instancemethod
sumber
Karena fungsi namespacing bagus (seperti yang ditunjukkan sebelumnya):
Ketika saya ingin menjelaskan tentang metode yang tidak mengubah status objek, saya menggunakan metode statis. Ini membuat orang-orang di tim saya enggan untuk mulai mengubah atribut objek dalam metode tersebut.
Ketika saya merefaktor kode yang benar-benar busuk, saya mulai dengan mencoba membuat metode
@staticmethod
sebanyak mungkin. Hal ini memungkinkan saya untuk mengekstrak metode ini ke dalam kelas - meskipun saya setuju, ini jarang sesuatu yang saya gunakan, itu memang berguna beberapa kali.sumber
Dalam perkiraan saya, tidak ada manfaat kinerja tunggal menggunakan
@staticmethod
s dibandingkan dengan hanya mendefinisikan fungsi di luar dan terpisah dari kelas yang seharusnya menjadi@staticmethod
dari.Satu-satunya hal yang saya katakan membenarkan keberadaan mereka adalah kenyamanan. Metode statis umum digunakan dalam bahasa pemrograman populer lainnya, jadi mengapa tidak python? Jika Anda ingin membuat fungsi dengan perilaku yang sangat terkait dengan kelas tempat Anda membuatnya tetapi fungsi tersebut tidak benar-benar mengakses / mengubah data internal instance kelas dengan cara yang membenarkan konseptualisasi sebagai tipikal metode kelas itu lalu berikan a
@staticmethod
di atasnya dan siapa pun yang membaca kode Anda akan segera belajar banyak tentang sifat metode dan hubungannya dengan kelas.Satu hal yang kadang-kadang ingin saya lakukan adalah menempatkan fungsionalitas yang banyak digunakan kelas saya secara internal ke dalam private
@staticmethod
. Dengan cara itu saya tidak mengacaukan API yang diekspos oleh modul saya dengan metode yang tidak perlu dilihat oleh siapa pun yang menggunakan modul saya apalagi menggunakannya.sumber
Metode statis hampir tidak memiliki alasan untuk menggunakan Python. Anda menggunakan salah satu metode instance atau metode kelas.
def method(self, args): self.member = something @classmethod def method(cls, args): cls.member = something @staticmethod def method(args): MyClass.member = something # The above isn't really working # if you have a subclass
sumber
staticmethod
atau setiap penjelasan apaclassmethod
atau mengapa dan bagaimana hal itu "lebih baik" dari yang statis.staticmethod
dalam dokumen untuk mendukung klaim Anda bahwa itu cruft, atau klaim Georg yangclassmethod
harus digunakan sebagai gantinya).