පංතියක් ආරම්භ නොකර මට ඇමතිය හැකි පයිතන්හි ස්ථිතික ක්රම තිබිය හැකිද?
ClassName.static_method()
පංතියක් ආරම්භ නොකර මට ඇමතිය හැකි පයිතන්හි ස්ථිතික ක්රම තිබිය හැකිද?
ClassName.static_method()
Answers:
ඔව්, ස්ථිතික ක්රම අලංකරණ යන්ත්රය භාවිතා කිරීම
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, ...): ...
Aticstaticmethod පෝරමය යනු ශ්රිත සැරසිලි කරුවෙකි - විස්තර සඳහා ශ්රිත අර්ථ දැක්වීම්වල ක්රියාකාරී අර්ථ දැක්වීම් බලන්න.
එය පන්තියේදී (වැනි
C.f()
) හෝ උදාහරණයක් ලෙස (වැනිC().f()
) හැඳින්විය හැකිය . එහි පන්තිය හැර උදාහරණය නොසලකා හරිනු ලැබේ.පයිතන්හි ස්ථිතික ක්රම ජාවා හෝ සී ++ හි ඇති ක්රම වලට සමාන වේ. වඩා දියුණු සංකල්පයක් සඳහා, බලන්න
classmethod()
.ස්ථිතික ක්රම පිළිබඳ වැඩි විස්තර සඳහා, සම්මත වර්ගය ධුරාවලියේ මත ලේඛගතකිරීම උපදෙස් සම්මත වර්ගය ධුරාවලියේ .
2.2 අනුවාදයේ නව.
2.4 අනුවාදයේ වෙනස් කර ඇත: ක්රියාකාරී සැරසිලි සින්ටැක්ස් එකතු කරන ලදි.
ClassName.methodName()
ස්ථිතික එකක් ලෙස හැඳින්වීමට හැකි වනු ඇත, එවිට ක්රමයට කිසිවක් ලබා self
නොදෙනු ඇත. ඔබ කී පරිදි, එය තවමත් ද ලෙස මෙම ක්රමය කතා කල හැකි වනු ඇත ClassInstance.methodName()
, සහ self
නොසලකා එහි නම, පළමු පරාමිතිය ලෙස ලබා දෙනු ඇත.
මම හිතන්නේ ස්ටීවන් ඇත්තටම හරි . මුල් ප්රශ්නයට පිළිතුරු සැපයීම සඳහා, පන්ති ක්රමයක් සැකසීම සඳහා, පළමු තර්කය ඇමතුම් අවස්ථාවක් නොවන බව උපකල්පනය කරන්න, ඉන්පසු ඔබ එම ක්රමය පන්තියෙන් පමණක් ඇමතීමට වග බලා ගන්න.
(මෙම පිළිතුර පයිතන් 3.x වෙත යොමු වන බව සලකන්න. පයිතන් 2.x හි දී ඔබට TypeError
පන්තියේම ක්රමය ඇමතීමට අවස්ථාව ලැබේ.)
උදාහරණයක් වශයෙන්:
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.rollCall () විසින් නිවැරදි තර්ක ගණනක් යවනු ඇත, නමුත් ව්යතිරේකයක් මතු කිරීමට ද හේතු වනු ඇත, මන්ද n දැන් සංඛ්යාත්මකව ශ්රිතය අපේක්ෂා කරන විට සුනඛ නිදසුනක් (එනම්, රෙක්ස්) නිරූපණය කරනු ඇත.
සැරසිලි පැමිණෙන්නේ මෙහිදීය: අපි "රෝල් කැල්" ක්රමයට පෙර නම්
@staticmethod
ක්රමවේදය ස්ථිතික බව පැහැදිලිව ප්රකාශ කිරීමෙන් අපට එය උදාහරණයකින් ඇමතිය හැකිය. දැන්,
rex.rollCall(-1)
වැඩ කරයි. ක්රම නිර්වචනයකට පෙර at ස්ටැටික්මෙතෝඩ් ඇතුළු කිරීම, උදාහරණයක් ලෙස තර්කයක් ලෙස යැවීම වළක්වයි.
Commentstaticmethod රේඛාව සමඟ සහ නැතිව පහත කේතය උත්සාහ කිරීමෙන් ඔබට මෙය සත්යාපනය කළ හැකිය.
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 ට්රේස්බැක් වෙතින් ආයුබෝවන් <අන්තිම ඇමතුම> පළමු තර්කය ලෙස ඩම්මි නිදසුන සමඟ කැඳවනු ලැබේ (ඒ වෙනුවට කිසිවක් නැත)
self
පළමු තර්කය ලෙස සම්මත වනු ඇත . (බලන්න: සැරසිලි කරන්නා)
self
එය කැඳවූ ආකාරය අනුව සුදුසු පරිදි යොමු කිරීමක් ඇතුළත් කරයි . පරීක්ෂණ නඩුව: pastebin.com/12DDV7DB .
staticmethod
decorator එක් පන්තිය හා නිදසුනක් දෙක මත කාර්යය කැඳවීමට (නිදසුනක් මත කාර්යය කරන විට මෙම විසඳුම අසාර්ථක) හැක.
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
සමහර සංරචක භාවිතා කිරීමට අදහස් කරන සන්දර්භය තුළ එය දැන් තව ටිකක් බුද්ධිමත් හා ස්වයං ලේඛනගත කිරීමක් බවට පත්ව ඇති අතර එය විශේෂිත පරීක්ෂණ අවස්ථා නම් කිරීම සඳහා මෙන්ම පරමාදර්ශී පරීක්ෂණ සඳහා පරීක්ෂණ මොඩියුලයන් සත්ය මොඩියුලයන් සමඟ සිතියම් ගත කරන්නේ කෙසේද යන්න පිළිබඳ approach ජු ප්රවේශයක් ද ඇත. .
ව්යාපෘතියේ උපයෝගිතා කේතය සංවිධානය කිරීම සඳහා මෙම ප්රවේශය ක්රියාත්මක කිරීම මට නිතර නිතර පෙනේ. බොහෝ විට, මිනිසුන් වහාම කඩිමුඩියේ utils
පැකේජයක් සාදා මොඩියුල 9 කින් අවසන් වන අතර ඉන් එකක් LOC 120 ක් වන අතර ඉතිරිය LOC දුසිම් දෙකකි. මම කැමතියි මෙය ආරම්භ කර එය පැකේජයක් බවට පරිවර්තනය කර මොඩියුල සැබවින්ම නිර්මාණය කිරීමට සුදුසු මෘගයන් සඳහා පමණි:
# 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))
ප්රතිදානය:
ප්රති ult ලය: 25
Aticstaticmethod භාවිතා කිරීම
class Arithmetic:
# create add static method
@staticmethod
def add(x, y):
return x + y
print('Result:', Arithmetic.add(15, 10))
ප්රතිදානය:
ප්රති ult ලය: 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 වස්තුවක තත්වයක් නොමැති බැවිනි. කෙසේ වෙතත්, cmath යනු සියල්ලම යම් ආකාරයකින් සම්බන්ධ වන ක්රම එකතුවකි. ඉහත මගේ උදාහරණයේ දී, cmath හි ඇති සියලුම කාර්යයන් යම් ආකාරයකින් සංකීර්ණ සංඛ්යා මත ක්රියා කරයි.
@staticmethod
ඔබට පළමුself
පරාමිතිය මඟ හැරිය හැකි විට, සැරසිලි එකතු කිරීම හෝ ශ්රිත දර්ශකයක් භාවිතා කරන්නේ ඇයි ? හොඳයි, වස්තුවක් සඳහාa
, ඔබට ඇමතීමට නොහැකි වනු ඇතa.your_static_method()
, එය වෙනත් භාෂාවලින් අවසර ඇත, නමුත් එය කෙසේ හෝ නරක පුරුද්දක් ලෙස සලකනු ලබන අතර සම්පාදකයා නිතරම ඒ ගැන අනතුරු අඟවයි