>>> class C(object):... pass...>>> def f():... pass...>>> staticmethod(f).__get__(None, C)<function f at 0x5c1cf0>>>> classmethod(f).__get__(None, C)<bound method type.f of <class '__main__.C'>>
class Cluster(object):
def _is_cluster_for(cls, name):"""see if this class is the cluster with this namethis is a classmethod"""return cls.__name__ == name_is_cluster_for = classmethod(_is_cluster_for)
#static methoddef getCluster(name):"""static factory method, should be in Cluster classreturns a cluster object for the given name"""for cls in Cluster.__subclasses__():if cls._is_cluster_for(name):return cls()getCluster = staticmethod(getCluster)
class Foo(object):
def a_normal_instance_method(self, arg_1, kwarg_2=None):'''Return a value that is a function of the instance with itsattributes, and other arguments such as arg_1 and kwarg2'''
@staticmethoddef a_static_method(arg_0):'''Return a value that is a function of arg_0. It does not know theinstance or class it is called from.'''
@classmethoddef a_class_method(cls, arg1):'''Return a value that is a function of the class and other arguments.respects subclassing, it is called with the class it is called from.'''
# demonstrate same function whether called from instance or not:>>> ', '.maketrans('ABC', 'abc'){65: 97, 66: 98, 67: 99}>>> str.maketrans('ABC', 'abc'){65: 97, 66: 98, 67: 99}
class Apple:
_counter = 0
@staticmethoddef about_apple():print('Apple is good for you.')
# note you can still access other member of the class# but you have to use the class instance# which is not very nice, because you have repeat yourself## For example:# @staticmethod# print('Number of apples have been juiced: %s' % Apple._counter)## @classmethod# print('Number of apples have been juiced: %s' % cls._counter)## @classmethod is especially useful when you move your function to another class,# you don't have to rename the referenced class
@classmethoddef make_apple_juice(cls, number_of_apples):print('Making juice:')for i in range(number_of_apples):cls._juice_this(i)
@classmethoddef _juice_this(cls, apple):print('Juicing apple %d...' % apple)cls._counter += 1
class Foo(object):@classmethoddef bar(cls):return "In Foo"
class Foo2(Foo):@classmethoddef bar(cls):return "In Foo2 " + cls.magic()@classmethoddef magic(cls):return "MAGIC"
print Foo2().bar()
class X(object):m=54 #will not be referenced
@staticmethoddef static_method():print "Referencing/calling a variable or function outside this class. E.g. Some global variable/function."
>>> class Klaus:@classmethoddef classmthd(*args):return args
@staticmethoddef staticmthd(*args):return args
# 1. Call classmethod without any arg>>> Klaus.classmthd()(__main__.Klaus,) # the class gets passed as the first argument
# 2. Call classmethod with 1 arg>>> Klaus.classmthd('chumma')(__main__.Klaus, 'chumma')
# 3. Call staticmethod without any arg>>> Klaus.staticmthd()()
# 4. Call staticmethod with 1 arg>>> Klaus.staticmthd('chumma')('chumma',)
#!python3
from os import systemsystem('cls')# % % % % % % % % % % % % % % % % % % % %
class DemoClass(object):# instance methods need a class instance and# can access the instance through 'self'def instance_method_1(self):return 'called from inside the instance_method_1()'
def instance_method_2(self):# an instance outside the class indirectly calls the static_methodreturn self.static_method() + ' via instance_method_2()'
# class methods don't need a class instance, they can't access the# instance (self) but they have access to the class itself via 'cls'@classmethoddef class_method(cls):return 'called from inside the class_method()'
# static methods don't have access to 'cls' or 'self', they work like# regular functions but belong to the class' namespace@staticmethoddef static_method():return 'called from inside the static_method()'# % % % % % % % % % % % % % % % % % % % %
# works even if the class hasn't been instantiatedprint(DemoClass.class_method() + '\n')''' called from inside the class_method() '''
# works even if the class hasn't been instantiatedprint(DemoClass.static_method() + '\n')''' called from inside the static_method() '''# % % % % % % % % % % % % % % % % % % % %
# >>>>> all methods types can be called on a class instance <<<<<# instantiate the classdemoclassObj = DemoClass()
# call instance_method_1()print(democlassObj.instance_method_1() + '\n')''' called from inside the instance_method_1() '''
# # indirectly call static_method through instance_method_2(), there's really no use# for this since a @staticmethod can be called whether the class has been# instantiated or notprint(democlassObj.instance_method_2() + '\n')''' called from inside the static_method() via instance_method_2() '''
# call class_method()print(democlassObj.class_method() + '\n')''' called from inside the class_method() '''
# call static_method()print(democlassObj.static_method())''' called from inside the static_method() '''
"""# whether the class is instantiated or not, this doesn't workprint(DemoClass.instance_method_1() + '\n')'''TypeError: TypeError: unbound method instancemethod() must be called withDemoClass instance as first argument (got nothing instead)'''"""
class Pointdef __init__(self, x, y):self.x = xself.y = y
@classmethoddef frompolar(cls, radius, angle):"""The `cls` argument is the `Point` class itself"""return cls(radius * cos(angle), radius * sin(angle))
@staticmethoddef angle(x, y):"""this could be outside the class, but we put it herejust because we think it is logically related to the class."""return atan(y, x)
p1 = Point(3, 2)p2 = Point.frompolar(3, pi/4)
angle = Point.angle(3, 2)
class MyClass:'''Instance method has a mandatory first attribute self which represent the instance itself.Instance method must be called by a instantiated instance.'''def method(self):return 'instance method called', self
'''Class method has a mandatory first attribute cls which represent the class itself.Class method can be called by an instance or by the class directly.Its most common using scenario is to define a factory method.'''@classmethoddef class_method(cls):return 'class method called', cls
'''Static method doesn’t have any attributes of instances or the class.It also can be called by an instance or by the class directly.Its most common using scenario is to define some helper or utility functions which are closely relative to the class.'''@staticmethoddef static_method():return 'static method called'
obj = MyClass()print(obj.method())print(obj.class_method()) # MyClass.class_method()print(obj.static_method()) # MyClass.static_method()
输出:
('instance method called', <__main__.MyClass object at 0x100fb3940>)('class method called', <class '__main__.MyClass'>)static method called
class DecoratorTest(object):
def __init__(self):pass
def doubler(self, x):return x*2
@classmethoddef class_doubler(cls, x): # we need to use 'cls' instead of 'self'; 'cls' reference to the class instead of an instance of the classreturn x*2
@staticmethoddef static_doubler(x): # no need adding 'self' here; static_doubler() could be just a function not inside the classreturn x*2
让我们看看它是如何工作的:
decor = DecoratorTest()
print(decor.doubler(5))# 10
print(decor.class_doubler(5)) # a call with an instance of a class# 10print(DecoratorTest.class_doubler(5)) # a direct call by the class itself# 10
# staticmethod could be called in the same way as classmethod.print(decor.static_doubler(5)) # as an instance of the class# 10print(DecoratorTest.static_doubler(5)) # or as a direct call# 10
employee_1 = Employee('Andrew', 'Brown', 85000)print(f'Number of employees: {Employee.NO_OF_EMPLOYEES}')employee_2 = Employee.employee_from_full_name('John Black', 95000)print(f'Number of employees: {Employee.NO_OF_EMPLOYEES}')
Number of employees: 1Number of employees: 2
print(Employee.get_employee_legal_obligations_txt())
1. An employee must complete 8 hours per working day2. ...
或来自类的实例:
employee_1 = Employee('Andrew', 'Brown', 85000)print(employee_1.get_employee_legal_obligations_txt())
1. An employee must complete 8 hours per working day2. ...
Convert a function to be a static method.
A static method does not receive an implicit first argument.To declare a static method, use this idiom:
class C:@staticmethoddef f(arg1, arg2, ...):...
It can be called either on the class (e.g. C.f()) or on an instance(e.g. C().f()). The instance is ignored except for its class.
Static methods in Python are similar to those found in Java or C++.For a more advanced concept, see the classmethod builtin."""
类方法(函数)->方法
Convert a function to be a class method.
A class method receives the class as implicit first argument,just like an instance method receives the instance.To declare a class method, use this idiom:
class C:@classmethoddef f(cls, arg1, arg2, ...):...
It can be called either on the class (e.g. C.f()) or on an instance(e.g. C().f()). The instance is ignored except for its class.If a class method is called for a derived class, the derived classobject is passed as the implied first argument.
Class methods are different than C++ or Java static methods.If you want those, see the staticmethod builtin.
class Foo:@classmethoddef bar(cls, id: int = None):query = session.query(a.id,a.name,a.address,)
if id is not None:query = query.filter(a.id == id)
return query
class Person:x = "Hello"def __init__(self, name):self.name = name
@classmethod # Heredef test1(cls):print(cls.x) # Class variable by `cls`cls.test2(cls) # Instance method by `cls`cls.test3() # Class method by `cls`cls.test4() # Static method by `cls`print()print(Person.x) # Class variable by class namePerson.test2("Test2") # Instance method by class namePerson.test3() # Class method by class namePerson.test4() # Static method by class name
def test2(self):print("Test2")
@classmethoddef test3(cls):print("Test3")
@staticmethoddef test4():print("Test4")
obj = Person("John")obj.test1() # By object
# Or
Person.test1() # By class name
# ...
@classmethoddef test1(cls):print(cls.name) # Instance variable by `cls`
# Or
print(Person.name) # Instance variable by class name# ...
obj = Person("John")obj.test1()
# Or
Person.test1()
发生以下错误:
属性错误:类型对象'Person'没有属性'name'
如果@classmethod没有cls:
# ...
@classmethoddef test1(): # Without "cls"print("Test1")
# ...
obj = Person("John")obj.test1()
# Or
Person.test1()
@classmethod无法调用,则发生如下错误:
test1()接受0个位置参数,但给出了1个
而且,在约定中使用cls的名称,因此其他名称而不是cls仍然可以工作,如下所示:
# ...
@classmethoddef test1(orange):print(orange.x) # Class variableorange.test2(orange) # Instance methodorange.test3() # Class methodorange.test4() # Static method
# ...
obj = Person("John")obj.test1()
# Or
Person.test1()
输出:
HelloTest2Test3Test4
@staticmethod:
例如,@staticmethod可以通过对象调用,也可以直接通过类名调用,如下所示:
class Person:x = "Hello"def __init__(self, name):self.name = name
@staticmethod # Heredef test1():print("Test1")
def test2(self):print("Test2")
@classmethoddef test3(cls):print("Test3")
@staticmethoddef test4():print("Test4")
obj = Person("John")obj.test1() # By object
# Or
Person.test1() # By class name
# ...
@staticmethoddef test1(self): # With "self"print(self)
# Or
@staticmethoddef test1(cls): # With "cls"print(cls)
# ...
obj = Person("John")obj.test1("Test1") # With an argument
# Or
Person.test1("Test1") # With an argument
输出:
Test1
否则,如果您不传递参数,如下所示:
# ...
@staticmethoddef test1(self): # With "self"print("Test1")
# Or
@staticmethoddef test1(cls): # With "cls"print("Test1")
# ...
obj = Person("John")obj.test1() # Without an argument
# Or
Person.test1() # Without an argument