1.概述
本文对比静态方法与类方法的差异与使用场合。
2.static method
对于有一些与类相关的功能,但不需要任何实例来执行某些工作,在这种情况下可以使用静态方法。静态方法是绑定到类而不是类的对象的方法。它无法访问或修改类状态。它存在于类中,因为该方法存在于类中是有意义的。静态方法不接收隐式第一个参数。
静态方法是属于类而不是类的实例的方法。静态方法不需要实例化。
Syntax:
class C(object):
@staticmethod
def fun(arg1, arg2, ...):
...
Returns: a static method for function fun.
当调用@staticmethod
修饰的函数时,我们不会像通常使用方法那样将类的实例传给它。这意味着该函数被放在类中,但它无法访问该类的实例,也就是说它不是类的成员函数(没有self入参)。
Example #1:
# Python program to
# demonstrate static methods
class Maths():
@staticmethod
def addNum(num1, num2):
return num1 + num2
# Driver's code
if __name__ == "__main__":
# Calling method of class
# without creating instance
res = Maths.addNum(1, 2)
print("The result is", res)
# The result is 3
Example #2:
# Python program to
# demonstrate static methods
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# a static method to check if a Person is adult or not.
@staticmethod
def isAdult(age):
return age > 18
# Driver's code
if __name__ == "__main__":
res = Person.isAdult(12)
print('Is person adult:', res)
res = Person.isAdult(22)
print('\nIs person adult:', res)
# Is person adult: False
# Is person adult: True
Python 中的staticmethod()
函数支持在类中定义静态方法,从而允许创建不需要访问特定于实例的数据的方法。以下是使用 staticmethod() 函数的示例。
class MathUtils:
@staticmethod
def add(a, b):
return a + b
result = MathUtils.add(9, 8)
print(result)
在代码中,创建了一个带有 greet()方法的类,然后使用 staticmethod()将其转换为静态方法,并且在不创建实例的情况下调用它,正如之前所讨论的,不需要创建类的实例来调用静态方法。
class demoClass:
def greet(msg):
return msg
# convert the add to a static method
demoClass.greet = staticmethod(demoClass.greet)
# we can access the method without
# creating the instance of class
print(demoClass.greet("Demo class is Today"))
如果我们不需要使用类属性,那么我们可以使用静态方法,在上面的代码中,add()方法不使用任何类属性,因此它使用 staticmethod()将其设置为静态,并且需要通过创建实例来调用 diff 方法,因为它使用类属性。
class demoClass:
def __init__(self, a, b):
self.a = a
self.b = b
def add(a, b):
return a+b
def diff(self):
return self.a-self.b
# convert the add to a static method
demoClass.add = staticmethod(demoClass.add)
# we can access the method without creating
# the instance of class
print(demoClass.add(1, 2))
# if we want to use properties of a class
# then we need to create a object
Object = demoClass(1, 2)
print(Object.diff())
Python 静态方法允许直接访问类变量。静态方法无法访问特定于实例的数据,因为它们不绑定到类的任何特定实例。但是,它们确实可以访问类级信息,其中包括类变量.
class MathUtils:
num = 40
@staticmethod
def double():
return MathUtils.num * 2
result = MathUtils.double()
print(result)
可以使用静态方法执行字符串格式化操作。在不访问特定于实例的数据的情况下,它们提供了一种在类中封装字符串格式逻辑的方法。
class Formatter:
@staticmethod
def format_name(first_name, last_name):
return f"{last_name}, {first_name}"
formatted_name = Formatter.format_name("For Geeks", "Geeks")
print(formatted_name)
3. class method
语法:classmethod(function)
参数 :该函数接受函数名称作为参数。
返回类型:此函数返回转换后的类方法
3.1 Python classmethod()函数
classmethod()方法绑定到类而不是对象。类方法可以由类和对象调用。可以使用类或对象调用这些方法。
3.2 类方法与静态方法
Python 中的类方法与静态方法之间的基本区别 ,以及何时在 Python 中使用类方法和静态方法。
- 类方法将 cls 作为第一个参数,而静态方法不需要特定参数。
- 类方法可以访问或修改类状态,而静态方法不能访问或修改类状态。
- 通常,静态方法对类状态一无所知。它们是实用程序类型的方法,采用一些参数并处理这些参数。另一方面,类方法必须将类作为参数。
- 我们在 Python 中使用@classmethod装饰器来创建一个类方法,并使用@staticmethod装饰器在 Python 中创建一个静态方法。
在下面示例中,我们将了解如何在 Python 中创建类方法。为此,我们创建了一个名为“Geeks”的类,其成员变量为“course”,并创建了一个名为“purchase”的函数来打印对象。现在,我们使用@classmethod
装饰器将该Geeks.purchase
方法传递到类方法中,该方法将被转换为类方法。有了类方法,我们可以调用函数“purchase”,而无需创建函数对象,直接使用类名“Geeks”。
class geeks:
course = 'DSA'
def purchase(obj):
print("Purchase course : ", obj.course)
geeks.purchase = classmethod(geeks.purchase)
geeks.purchase()
# Purchase course : DSA
3.3 使用classmethod() 创建类方法
在创建print_name()这一行之前创建print_name 类方法。 它只能用对象调用,不能用类调用,现在这个方法可以调用为classmethod print_name() 方法就称为类方法。
class Student:
# create a variable
name = "Geeksforgeeks"
# create a function
def print_name(obj):
print("The name is : ", obj.name)
# create print_name classmethod
# before creating this line print_name()
# It can be called only with object not with class
Student.print_name = classmethod(Student.print_name)
# now this method can be called as classmethod
# print_name() method is called a class method
Student.print_name()
3.4 使用 Class 方法的工厂方法
classmethod() 函数的使用用于工厂设计模式,我们希望使用类名而不是对象调用许多函数。
# Python program to demonstrate
# use of a class method and static method.
from datetime import date
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# a class method to create a
# Person object by birth year.
@classmethod
def fromBirthYear(cls, name, year):
return cls(name, date.today().year - year)
def display(self):
print("Name : ", self.name, "Age : ", self.age)
person = Person('mayank', 21)
person.display()
3.5 类方法用于继承
在此示例中,我们将创建具有两个类的 Python 类层次结构, 并演示了类方法和继承的用法。
from datetime import date
# random Person
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@staticmethod
def from_FathersAge(name, fatherAge, fatherPersonAgeDiff):
return Person(name, date.today().year - fatherAge + fatherPersonAgeDiff)
@classmethod
def from_BirthYear(cls, name, birthYear):
return cls(name, date.today().year - birthYear)
def display(self):
print(self.name + "'s age is: " + str(self.age))
class Man(Person):
sex = 'Female'
man = Man.from_BirthYear('John', 1985)
print(isinstance(man, Man))
man1 = Man.from_FathersAge('John', 1965, 20)
print(isinstance(man1, Man))
3.6 Python @classmethod装饰器
@classmethod装饰器是一个内置的函数装饰器,它是在定义函数后计算的表达式。该评估的结果会遮蔽函数定义。类方法接收类作为隐式的第一个参数,就像实例方法接收实例一样。
3.7 classmethod Decorator 的语法
C类(对象):
@classmethod
def fun(cls, arg1, arg2, ...):
….
其中
- fun:需要转换为类方法的函数
- returns:函数的类方法。
注意:
- 类方法是绑定到类而不是类对象的方法。
- 它们可以访问类的状态,因为它需要指向类而不是对象实例的类参数。
- 它可以修改将应用于该类的所有实例的类状态。例如,它可以修改适用于所有实例的类变量。
在下面的例子中,我们使用 staticmethod()和 classmethod() 来检查一个人是否是成年人。
# Python program to demonstrate
# use of a class method and static method.
from datetime import date
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# a class method to create a
# Person object by birth year.
@classmethod
def fromBirthYear(cls, name, year):
return cls(name, date.today().year - year)
# a static method to check if a
# Person is adult or not.
@staticmethod
def isAdult(age):
return age > 18
person1 = Person('mayank', 21)
person2 = Person.fromBirthYear('mayank', 1996)
print(person1.age)
print(person2.age)
# print the result
print(Person.isAdult(22))
""" result is: """
21
27
True