পাইথনে স্থিতিশীল পদ্ধতিগুলি থাকা কি সম্ভব যা আমি ক্লাস শুরু না করে কল করতে পারি, যেমন:
ClassName.static_method()
পাইথনে স্থিতিশীল পদ্ধতিগুলি থাকা কি সম্ভব যা আমি ক্লাস শুরু না করে কল করতে পারি, যেমন:
ClassName.static_method()
উত্তর:
হ্যাঁ, স্ট্যাটিকমেডোথ ডেকোরেটর ব্যবহার করে
class MyClass(object):
@staticmethod
def the_static_method(x):
print(x)
MyClass.the_static_method(2) # outputs 2
নোট করুন যে কোনও কোড ডিকোরিটারের staticmethod
পরিবর্তে একটি ফাংশন হিসাবে ব্যবহার করে একটি স্ট্যাটিক পদ্ধতি সংজ্ঞায়নের পুরানো পদ্ধতিটি ব্যবহার করতে পারে । এটি কেবল তখনই ব্যবহার করা উচিত যদি আপনাকে পাইথনের প্রাচীন সংস্করণগুলি সমর্থন করতে হয় (2.2 এবং 2.3)
class MyClass(object):
def the_static_method(x):
print(x)
the_static_method = staticmethod(the_static_method)
MyClass.the_static_method(2) # outputs 2
এটি সম্পূর্ণরূপে প্রথম উদাহরণের সাথে মিল (ব্যবহার করে @staticmethod
), কেবল দুর্দান্ত ডেকোরেটর সিনট্যাক্স ব্যবহার না করে
অবশেষে, staticmethod()
অল্প ব্যবহার করুন ! খুব অল্প কিছু পরিস্থিতি রয়েছে যেখানে পাইথনে স্থির পদ্ধতিগুলি প্রয়োজনীয় এবং আমি তাদের বহুবার ব্যবহার করতে দেখেছি যেখানে পৃথক "শীর্ষ-স্তরের" ফাংশনটি আরও পরিষ্কার হত।
ডকুমেন্টেশন থেকে নিম্নলিখিতটি ভারব্যাটিম :
একটি স্থিতিশীল পদ্ধতি একটি অন্তর্নিহিত প্রথম যুক্তি গ্রহণ করে না। একটি স্থিতিশীল পদ্ধতি ঘোষণা করতে, এই প্রতিমাটি ব্যবহার করুন:
class C: @staticmethod def f(arg1, arg2, ...): ...
@Staticmethod ফর্ম একটি ফাংশন প্রসাধক - ফাংশন সংজ্ঞা বিবরণ দেখুন ফাংশন সংজ্ঞা বিস্তারিত জানার জন্য।
এটি ক্লাসে (যেমন
C.f()
) বা কোনও উদাহরণে (যেমনC().f()
) বলা যেতে পারে । উদাহরণটি এর শ্রেণি ব্যতীত উপেক্ষা করা হবে।পাইথনের স্ট্যাটিক পদ্ধতি জাভা বা সি ++ এর মতো পাওয়া যায়। আরও উন্নত ধারণার জন্য দেখুন
classmethod()
।স্ট্যাটিক পদ্ধতি উপর আরও তথ্যের জন্য, আদর্শ টাইপ অনুক্রমের দস্তাবেজ পড়ুন মান টাইপ অনুক্রমের ।
সংস্করণ ২.২ এ নতুন।
সংস্করণ ২.৪ এ পরিবর্তিত হয়েছে: ফাংশন ডেকোরেটর সিনট্যাক্স যুক্ত হয়েছে।
ClassName.methodName()
, যেমন এটি একটি স্থিতিশীল, এবং তারপরে কোনও self
পদ্ধতিতে সরবরাহ করা হবে না। হিসাবে আপনি বলেন, এটা এখনও সম্ভব হবে নামেও এই পদ্ধতি কল ClassInstance.methodName()
, এবং self
প্রথম প্যারামিটার হিসাবে সরবরাহ করা হবে, তার নাম যাই হোক না।
আমি মনে করি যে স্টিভেন আসলেই সঠিক । মূল প্রশ্নের উত্তর দেওয়ার জন্য, তারপরে, কোনও শ্রেণি পদ্ধতি স্থাপনের জন্য, কেবল ধরে নিন যে প্রথম যুক্তিটি একটি কলিং দৃষ্টান্ত হয়ে উঠছে না, এবং তারপরে নিশ্চিত হয়ে নিন যে আপনি কেবল ক্লাস থেকে পদ্ধতিটি কল করেছেন।
(দ্রষ্টব্য যে এই উত্তরটি পাইথন ৩.x বোঝায় Py পাইথন ২.x এ আপনি TypeError
ক্লাসে পদ্ধতিটি কল করার জন্য একটি পাবেন get )
উদাহরণ স্বরূপ:
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
def rollCall(n): #this is implicitly a class method (see comments below)
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
এই কোডটিতে, "রোলক্যাল" পদ্ধতিটি ধরে নিয়েছে যে প্রথম যুক্তিটি উদাহরণ নয় (যেমন এটি হবে যদি এটি শ্রেণীর পরিবর্তে কোনও উদাহরণ দ্বারা ডাকা হত)। যতক্ষণ না উদাহরণের চেয়ে ক্লাস থেকে "রোলক্যাল" কল করা হবে ততক্ষণ কোডটি ঠিকঠাকভাবে কাজ করবে। যদি আমরা কোনও উদাহরণ থেকে "রোলকল" কল করার চেষ্টা করি, যেমন:
rex.rollCall(-1)
তবে এটি একটি ব্যতিক্রম উত্থাপিত হতে পারে কারণ এটি দুটি আর্গুমেন্ট প্রেরণ করবে: নিজে এবং -1, এবং "রোলকেল" কেবল একটি যুক্তি গ্রহণ করার জন্য সংজ্ঞায়িত করা হয়েছে।
ঘটনাচক্রে, rex.rolCall () আর্গুমেন্টের সঠিক সংখ্যা প্রেরণ করবে, তবে একটি ব্যতিক্রমও উত্থাপন করতে পারে কারণ এখন n একটি কুকুর উদাহরণকে উপস্থাপন করবে (যেমন, রেক্স) যখন ফাংশনটি n সংখ্যাসূচক হওয়ার প্রত্যাশা করে।
এখানেই সাজসজ্জাটি আসে: যদি আমরা "রোলক্যাল" পদ্ধতিটি পূর্বে করি
@staticmethod
তারপরে, স্পষ্টভাবে উল্লেখ করে যে পদ্ধতিটি অচল, আমরা এমনকি এটি একটি উদাহরণ থেকে কল করতে পারি। এখন,
rex.rollCall(-1)
কাজ করবে কোনও পদ্ধতির সংজ্ঞার আগে @staticmethod এর সন্নিবেশ, তারপরে, নিজেকে একটি যুক্তি হিসাবে প্রেরণ করা থেকে বিরত থাকে।
আপনি @ স্ট্যাটিকমেডোথ লাইনের সাথে মন্তব্য না করে এবং নীচের কোড ব্যবহার করে যাচাই করতে পারেন।
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
@staticmethod
def rollCall(n):
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
rex.rollCall(-1)
TypeError: unbound method rollCall() must be called with Dog instance as first argument (got int instance instead)
T.my_static_method()
বা type(my_t_instance).my_static_method()
, যেহেতু এটি পরিষ্কার হয় এবং তাত্ক্ষণিকভাবে স্পষ্ট করে দেয় যে আমি একটি স্ট্যাটিক পদ্ধতি বলছি।
হ্যাঁ, স্ট্যাটিকমেডোথ ডেকোরিটারটি দেখুন :
>>> class C:
... @staticmethod
... def hello():
... print "Hello World"
...
>>> C.hello()
Hello World
আপনার সত্যিকার অর্থে @staticmethod
ডেকোরেটর ব্যবহার করার দরকার নেই । কেবলমাত্র একটি পদ্ধতি ঘোষণা করা (এটি স্ব প্যারামিটারটি আশা করে না) এবং এটি ক্লাস থেকে কল করে। আপনি যদি কোনও উদাহরণ থেকেও এটি কল করতে সক্ষম হতে চান তবে সারণি কেবল সেখানে থাকে (যা আপনি করতে চেয়েছিলেন তা নয়)
বেশিরভাগ ক্ষেত্রে, আপনি কেবল ফাংশনগুলি ব্যবহার করেন যদিও ...
class Dummy: def static1(): print "hello from static1" @staticmethod def static2(): print "hello from static2" Dummy.static2() Dummy.static1()
: স্ট্যাটিক 2 ট্রেসব্যাক থেকে হ্যালো <অতি সাম্প্রতিক কল শেষ>> ফাইল "ll.py", 46 নং, <মডুল> ডামি.স্ট্যাটিক 1 () টাইপ এরর: আনবাউন্ড পদ্ধতি স্ট্যাটিক 1 () হতে হবে ডামি উদাহরণ দিয়ে প্রথম যুক্তি হিসাবে ডাকা হয়েছিল (পরিবর্তে কিছুই পেল না)
self
প্রথম যুক্তি হিসাবে পাস করবে যদি না আপনি এটি না বলে থাকেন। (দেখুন: শোভাকর)
self
এটি কীভাবে ডাকা হয় তার উপর নির্ভর করে যথাযথভাবে একটি রেফার্ট প্রবেশ করান । পরীক্ষার কেস: পেস্টবিন . com /12 ডিডিভি 7 ডিবি ।
staticmethod
প্রসাধক এক উভয় শ্রেণী এবং একটি দৃষ্টান্ত (এই সমাধান ব্যর্থ হলে একটি দৃষ্টান্ত উপর ফাংশন কলিং) এ ফাংশন কল করতে পারবেন।
class C: def callme(): print('called'); C.callme()
পাইথনে স্থির পদ্ধতি?
পাইথনে স্থির পদ্ধতি থাকা কি সম্ভব তাই আমি কোনও ক্লাস শুরু না করেই তাদের কল করতে পারি, যেমন:
ClassName.StaticMethod()
হ্যাঁ, স্থির পদ্ধতিগুলি এ জাতীয়ভাবে তৈরি করা যেতে পারে (যদিও পদ্ধতিগুলির জন্য ক্যামেলকেসের পরিবর্তে আন্ডারস্কোরগুলি ব্যবহার করা কিছুটা পাইথোনিক ):
class ClassName(object):
@staticmethod
def static_method(kwarg1=None):
'''return a value that is a function of kwarg1'''
উপরেরটি সজ্জা সিনট্যাক্স ব্যবহার করে। এই বাক্য গঠনটি সমান
class ClassName(object):
def static_method(kwarg1=None):
'''return a value that is a function of kwarg1'''
static_method = staticmethod(static_method)
আপনি যেমন বর্ণনা করেছেন ঠিক তেমন এটি ব্যবহার করা যেতে পারে:
ClassName.static_method()
স্ট্যাটিক পদ্ধতির একটি অন্তর্নির্মিত উদাহরণ str.maketrans()
পাইথন 3-এ রয়েছে, যা string
পাইথন 2- এ মডিউলে একটি ফাংশন ছিল ।
আপনি বর্ণনা করার সাথে সাথে ব্যবহার করা যেতে পারে এমন আরেকটি বিকল্প হ'ল classmethod
, পার্থক্যটি হ'ল শ্রেণীবদ্ধ একটি অন্তর্নিহিত প্রথম যুক্তি হিসাবে শ্রেণিটি পায় এবং যদি উপ-শ্রেণিবদ্ধ হয়, তবে এটি অন্তর্নিহিত প্রথম যুক্তি হিসাবে সাবক্লাস পায়।
class ClassName(object):
@classmethod
def class_method(cls, kwarg1=None):
'''return a value that is a function of the class and kwarg1'''
মনে রাখবেন যে cls
প্রথম যুক্তির জন্য প্রয়োজনীয় নাম নয়, তবে বেশিরভাগ অভিজ্ঞ পাইথন কোডার যদি আপনি অন্য কোনও কিছু ব্যবহার করেন তবে এটি খারাপভাবে বিবেচনা করবে।
এগুলি সাধারণত বিকল্প নির্মাণকারী হিসাবে ব্যবহৃত হয়।
new_instance = ClassName.class_method()
একটি অন্তর্নির্মিত উদাহরণ হ'ল dict.fromkeys()
:
new_dict = dict.fromkeys(['key1', 'key2'])
স্থির পদ্ধতি অবজেক্টগুলি কীভাবে আচরণ করে তার বিশদগুলি বাদ দিয়ে , আপনার মডিউল-স্তরের কোডটি সংগঠিত করার সময় আপনি তাদের সাথে স্ট্রাইক করতে পারেন এমন এক ধরণের সৌন্দর্য রয়েছে।
# garden.py
def trim(a):
pass
def strip(a):
pass
def bunch(a, b):
pass
def _foo(foo):
pass
class powertools(object):
"""
Provides much regarded gardening power tools.
"""
@staticmethod
def answer_to_the_ultimate_question_of_life_the_universe_and_everything():
return 42
@staticmethod
def random():
return 13
@staticmethod
def promise():
return True
def _bar(baz, quux):
pass
class _Dice(object):
pass
class _6d(_Dice):
pass
class _12d(_Dice):
pass
class _Smarter:
pass
class _MagicalPonies:
pass
class _Samurai:
pass
class Foo(_6d, _Samurai):
pass
class Bar(_12d, _Smarter, _MagicalPonies):
pass
...
# tests.py
import unittest
import garden
class GardenTests(unittest.TestCase):
pass
class PowertoolsTests(unittest.TestCase):
pass
class FooTests(unittest.TestCase):
pass
class BarTests(unittest.TestCase):
pass
...
# interactive.py
from garden import trim, bunch, Foo
f = trim(Foo())
bunch(f, Foo())
...
# my_garden.py
import garden
from garden import powertools
class _Cowboy(garden._Samurai):
def hit():
return powertools.promise() and powertools.random() or 0
class Foo(_Cowboy, garden.Foo):
pass
এটি এখন কিছুটা স্বজ্ঞাত এবং স্ব-ডকুমেন্টিংয়ে পরিণত হয়েছে যার প্রসঙ্গে নির্দিষ্ট উপাদানগুলি ব্যবহারের জন্য বোঝানো হয়েছে এবং এটি পৃথক পরীক্ষার কেসগুলির নামকরণের পাশাপাশি আদর্শবাদীদের পরীক্ষা-নিরীক্ষার অধীনে পরীক্ষার মডিউলগুলিকে কীভাবে প্রকৃত মডিউলগুলিতে মানচিত্রের জন্য একটি সরল পদ্ধতি অবলম্বন করার জন্য একটি আদর্শ পদ্ধতি রয়েছে p ।
আমি প্রায়শই কোনও প্রকল্পের ইউটিলিটি কোডটি সংগঠিত করতে এই পদ্ধতির প্রয়োগ করা কার্যকর মনে করি। বেশিরভাগ ক্ষেত্রেই লোকেরা তাত্ক্ষণিকভাবে ছুটে আসে এবং একটি utils
প্যাকেজ তৈরি করে এবং 9 টি মডিউল নিয়ে শেষ হয় যার মধ্যে একটিতে 120 টি এলওসি থাকে এবং বাকীটি দুটি ডজন এলওসি হয়। আমি এটির সাথে শুরু করতে এবং এটি একটি প্যাকেজে রূপান্তর করতে এবং কেবলমাত্র তাদের জন্য উপযুক্ত যে জানোয়ারগুলির জন্য মডিউল তৈরি করতে পছন্দ করি:
# utils.py
class socket(object):
@staticmethod
def check_if_port_available(port):
pass
@staticmethod
def get_free_port(port)
pass
class image(object):
@staticmethod
def to_rgb(image):
pass
@staticmethod
def to_cmyk(image):
pass
সম্ভবত সবচেয়ে সহজ বিকল্পটি কেবল ক্লাসের বাইরে এই ফাংশনগুলি রাখা:
class Dog(object):
def __init__(self, name):
self.name = name
def bark(self):
if self.name == "Doggy":
return barking_sound()
else:
return "yip yip"
def barking_sound():
return "woof woof"
এই পদ্ধতিটি ব্যবহার করে, অভ্যন্তরীণ অবজেক্টের স্থিতি সংশোধন বা ব্যবহার করা ফাংশন (পার্শ্ব প্রতিক্রিয়াগুলি) শ্রেণিতে রাখা যেতে পারে এবং পুনরায় ব্যবহারযোগ্য ইউটিলিটি ফাংশনগুলি বাইরে সরানো যেতে পারে।
যাক এই ফাইলটি বলা হয় dogs.py
। এগুলি ব্যবহার করতে, আপনি dogs.barking_sound()
পরিবর্তে কল করবেন dogs.Dog.barking_sound
।
শ্রেণির অংশ হওয়ার জন্য যদি আপনার সত্যিই স্ট্যাটিক পদ্ধতি প্রয়োজন, আপনি স্ট্যাটিকমেডোথ ডেকোরিটারটি ব্যবহার করতে পারেন ।
সুতরাং, স্ট্যাটিক পদ্ধতিগুলি এমন একটি পদ্ধতি যা কোনও শ্রেণীর অবজেক্ট তৈরি না করে কল করা যায়। উদাহরণ স্বরূপ :-
@staticmethod
def add(a, b):
return a + b
b = A.add(12,12)
print b
উপরের উদাহরণে পদ্ধতিটিকে add
শ্রেণীর নাম দিয়ে ডাকা হয় A
বস্তুর নাম নয়।
পাইথন স্ট্যাটিক পদ্ধতি দুটি উপায়ে তৈরি করা যেতে পারে।
স্ট্যাটিকমেথড () ব্যবহার করে
class Arithmetic:
def add(x, y):
return x + y
# create add static method
Arithmetic.add = staticmethod(Arithmetic.add)
print('Result:', Arithmetic.add(15, 10))
আউটপুট:
ফলাফল: 25
টুইটারে
class Arithmetic:
# create add static method
@staticmethod
def add(x, y):
return x + y
print('Result:', Arithmetic.add(15, 10))
আউটপুট:
ফলাফল: 25
আমি সময়ে সময়ে এই প্রশ্নের মুখোমুখি। ব্যবহারের ক্ষেত্রে এবং উদাহরণটি আমি পছন্দ করি তা হ'ল:
jeffs@jeffs-desktop:/home/jeffs $ python36
Python 3.6.1 (default, Sep 7 2017, 16:36:03)
[GCC 6.3.0 20170406] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath
>>> print(cmath.sqrt(-4))
2j
>>>
>>> dir(cmath)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'inf', 'infj', 'isclose', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'nan', 'nanj', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau']
>>>
ক্লাস চ্যামথের একটি অবজেক্ট তৈরি করা কোনও অর্থবোধ করে না, কারণ একটি চামথ অবজেক্টে কোনও রাজ্য নেই। তবে, cmath হ'ল পদ্ধতিগুলির সংকলন যা কোনওভাবেই সম্পর্কিত। উপরের আমার উদাহরণে, cmath এর সমস্ত ক্রিয়াকলাপ কোনওভাবে জটিল সংখ্যায় কাজ করে।
@staticmethod
আপনি কেবল প্রথমself
প্যারামিটারটি এড়াতে পারবেন কেন সজ্জা যুক্ত করবেন বা কোনও ফাংশন পয়েন্টার ব্যবহার করবেন ? ওয়েল, একটি বস্তুর জন্যa
, তাই না কল করতে সক্ষম হবেa.your_static_method()
, যা অন্যান্য ভাষায় অনুমোদিত হয়, কিন্তু এটা যাহাই হউক না কেন একটি খারাপ অভ্যাস বিবেচনা করা হয় এবং কম্পাইলার সবসময় এটা সম্পর্কে সতর্ক করে