我已经阅读了Python中的类方法是什么?,但是这篇文章中的示例比较复杂。我正在寻找一个明确、简单、简洁的Python类方法实际应用案例。
你能给出一个小的、具体的使用场景,说明在这种情况下Python类方法是正确的工具吗?
我已经阅读了Python中的类方法是什么?,但是这篇文章中的示例比较复杂。我正在寻找一个明确、简单、简洁的Python类方法实际应用案例。
你能给出一个小的、具体的使用场景,说明在这种情况下Python类方法是正确的工具吗?
初始化的辅助方法:
class MyStream(object):
@classmethod
def from_file(cls, filepath, ignore_comments=False):
with open(filepath, 'r') as fileobj:
for obj in cls(fileobj, ignore_comments):
yield obj
@classmethod
def from_socket(cls, socket, ignore_comments=False):
raise NotImplemented # Placeholder until implemented
def __init__(self, iterable, ignore_comments=False):
...
classmethod
зҡ„е…ёеһӢз”Ёжі•гҖӮдёҺе…¶staticmethod
зӣёжҜ”пјҢе®ғ们дёҺеӯҗзұ»зҡ„зӣёдә’дҪңз”ЁиүҜеҘҪгҖӮ - ncoghlan嗯,__new__
是一个非常重要的类方法。通常这是实例化对象的地方。
所以,当调用dict()
时,当然会调用dict.__new__
,但有另一种方便的方法可以创建字典,即使用类方法dict.fromkeys()
例如:
>>> dict.fromkeys("12345")
{'1': None, '3': None, '2': None, '5': None, '4': None}
fromkeys
也是一个类方法。 - senderle__new__
隐式地转换为静态方法。在实例创建过程中还有其他机制,将适当的类对象作为第一个参数传递进去。dict.fromkeys
是一个真正的类方法的绝佳示例。 - ncoghlan__new__
并非实际上是这样实现的,它仍然依赖于与classmethod
相同的概念。 - ncoghlan我不知道,就像命名构造函数这样的东西?
class UniqueIdentifier(object):
value = 0
def __init__(self, name):
self.name = name
@classmethod
def produce(cls):
instance = cls(cls.value)
cls.value += 1
return instance
class FunkyUniqueIdentifier(UniqueIdentifier):
@classmethod
def produce(cls):
instance = super(FunkyUniqueIdentifier, cls).produce()
instance.name = "Funky %s" % instance.name
return instance
使用方法:
>>> x = UniqueIdentifier.produce()
>>> y = FunkyUniqueIdentifier.produce()
>>> x.name
0
>>> y.name
Funky 1
使用@classmethod
的最大原因是为了创建一个旨在被继承的替代构造函数,这在多态中非常有用。例如:
class Shape(object):
# this is an abstract class that is primarily used for inheritance defaults
# here is where you would define classmethods that can be overridden by inherited classes
@classmethod
def from_square(cls, square):
# return a default instance of cls
return cls()
请注意,Shape
是一个抽象类,它定义了一个类方法from_square
。由于Shape
没有真正被定义,所以它不知道如何从Square
中派生自己,因此它只返回该类的默认实例。
然后,继承类可以定义自己版本的此方法:
class Square(Shape):
def __init__(self, side=10):
self.side = side
@classmethod
def from_square(cls, square):
return cls(side=square.side)
class Rectangle(Shape):
def __init__(self, length=10, width=10):
self.length = length
self.width = width
@classmethod
def from_square(cls, square):
return cls(length=square.side, width=square.side)
class RightTriangle(Shape):
def __init__(self, a=10, b=10):
self.a = a
self.b = b
self.c = ((a*a) + (b*b))**(.5)
@classmethod
def from_square(cls, square):
return cls(a=square.length, b=square.width)
class Circle(Shape):
def __init__(self, radius=10):
self.radius = radius
@classmethod
def from_square(cls, square):
return cls(radius=square.length/2)
使用此方法可以使您以多态方式处理所有这些未实例化的类
square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle):
this_shape = polymorphic_class.from_square(square)
你可能会觉得这一切都很顺利,但是为什么我不能只使用@staticmethod
来实现相同的多态行为呢:
class Circle(Shape):
def __init__(self, radius=10):
self.radius = radius
@staticmethod
def from_square(square):
return Circle(radius=square.length/2)
答案:你可以这样做,但是由于在方法中必须明确调用Circle
,所以你不会获得继承的好处。这意味着如果我从一个继承的类中调用它而没有进行覆盖,每次都将得到Circle
。class Hexagon(Shape):
def __init__(self, side=10):
self.side = side
# note the absence of classmethod here, this will use from_square it inherits from shape
在这里,您可以不定义@classmethod
,它将使用Shape.from_square
的逻辑,同时保留cls
并返回相应的形状。
square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle, Hexagon):
this_shape = polymorphic_class.from_square(square)
rect = Rectangle(15,5)
rt = RightTriangle(5,15)
cir = Circle(50)
for polymorphic_class in (rect,square,cir,rt):
this_shape = polymorphic_class.from_square(polymorphic_class)
print("初始化类 ",type(this_shape).__name__)```
- Alferd Nobel我发现我最常使用@classmethod
将一段代码与类关联起来,以避免创建全局函数。这种情况通常是在我不需要使用类的实例就能使用该代码的情况下。
例如,我可能有一个数据结构,只有符合某些模式的键才被视为有效。我可能希望从类内部和外部使用它。但是,我不想再创建另一个全局函数:
def foo_key_is_valid(key):
# code for determining validity here
return valid
我更愿意将这段代码与其相关的类分组:
class Foo(object):
@classmethod
def is_valid(cls, key):
# code for determining validity here
return valid
def add_key(self, key, val):
if not Foo.is_valid(key):
raise ValueError()
..
# lets me reuse that method without an instance, and signals that
# the code is closely-associated with the Foo class
Foo.is_valid('my key')
add_key
中,Foo.is_valid(key)
也可以是self.is_valid(key)
。更多信息请参考:http://docs.python.org/library/functions.html#classmethod - cerberosfrom enum import Enum
from datetime import date
class Weekday(Enum):
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
SUNDAY = 7
#
@classmethod
def from_date(cls, date):
return cls(date.isoweekday())
Weekday.from_date(date.today())
<Weekday.TUESDAY: 2>
in class MyClass(object):
'''
classdocs
'''
obj=0
x=classmethod
def __init__(self):
'''
Constructor
'''
self.nom='lamaizi'
self.prenom='anas'
self.age=21
self.ville='Casablanca'
if __name__:
ob=MyClass()
print(ob.nom)
print(ob.prenom)
print(ob.age)
print(ob.ville)