装饰的功能@staticmethod和装饰的功能有什么区别@classmethod?
何时以及如何在python中使用静态方法?我们已经建立了使用类方法作为工厂方法来创建对象的实例应该尽可能避免.换句话说,使用类方法作为替代构造函数并不是最佳实践(请参阅python对象的Factory方法 - 最佳实践).
假设我有一个用于表示数据库中某些实体数据的类.想象一下,数据是一个dict包含字段名称和字段值的对象,其中一个字段是使数据唯一的ID号.
class Entity(object):
def __init__(self, data, db_connection):
self._data = data
self._db_connection
Run Code Online (Sandbox Code Playgroud)
这里我的__init__方法采用实体数据dict对象.假设我只有一个ID号,我想创建一个Entity实例.首先,我需要找到其余的数据,然后创建我的Entity对象的实例.从我之前的问题中,我们确定应尽可能避免使用类方法作为工厂方法.
class Entity(object):
@classmethod
def from_id(cls, id_number, db_connection):
filters = [['id', 'is', id_number]]
data = db_connection.find(filters)
return cls(data, db_connection)
def __init__(self, data, db_connection):
self._data = data
self._db_connection
# Create entity
entity = Entity.from_id(id_number, db_connection)
Run Code Online (Sandbox Code Playgroud)
上面是一个例子,说明如果有替代方案,不做或至少不做什么.现在我想知道是否编辑我的类方法,以便它更像是一个实用工具方法,而更少的工厂方法是一个有效的解决方案.换句话说,以下示例是否符合使用静态方法的最佳实践.
class Entity(object):
@staticmethod
def data_from_id(id_number, db_connection):
filters = [['id', 'is', id_number]]
data = db_connection.find(filters)
return data
# Create entity …Run Code Online (Sandbox Code Playgroud) 我来自java背景,所以我在这里有点困惑。
考虑下面的代码片段:
class A():
def __init__(self, **kwargs):
self.obj_var = "I am obj var"
@classmethod
def class_method(cls):
print cls.obj_var # this line is in question here
cls.cls_obj = "I m class object"
return cls.cls_obj
Run Code Online (Sandbox Code Playgroud)
这会引发错误:
In [30]: a = A()
In [31]: a.obj_var
Out[31]: 'I am obj var'
In [32]: a.class_method()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-32-3dcd9d512548> in <module>()
----> 1 a.class_method()
<ipython-input-29-9c0d341ad75f> in class_method(cls)
8 @classmethod
9 def class_method(cls):
---> 10 print cls.obj_var
11 cls.cls_obj = "I m …Run Code Online (Sandbox Code Playgroud) python instance-variables decorator class-method python-decorators
我正在研究这个Python模块,它由几个文件组成.这些文件实际上很少是独立的,并且意味着要做一个非常具体的工作.我知道这样一个事实:这些文件只有一个实例(模块?),而且不多,因为这种工作是顺序的,只需要一次.
让我们以CXXParser我目前正在构建的这个模块为例:
例程简单明了 - 获取c ++文件,解析它,并将其"转换"为其他内容.由于我来自c ++世界,我立即开始在Python中寻找静态方法和单例.对于这个例子的使用,我有'public' parse函数,以及这个模块的许多'内部'函数,它实际上解析了文件.
我想知道,"Pythonic"的做法是什么?我开始四处寻找正确的方法,但只是感到困惑.因为我想到了单身 - 我看到了这个问题,并且从阅读答案开始,我开始在模块级实现它.但是,再一次,我观看了Python核心开发人员Raymond Hettinger的几个视频,并且他提到 - 几次 - 全局变量都很糟糕,并且最好使用类级变量.
这些是我目前面临的两个选择:
A.使用classmethods类:
#cxxparser.py
class CXXParser(object):
filename = ''
cflags = ''
translation_unit = None
def __init__(self, filename, cflags = None):
super(CXXParser, self).__init__()
filename = filename
if cflags:
cflags = cflags
@classmethod
def get_tu(cls):
'get the tu from the file'
return tu
@classmethod
def parse(cls):
...
#call some inner functions
#for example:
translation_unit = cls.get_tu() …Run Code Online (Sandbox Code Playgroud) 据我所知,Python中至少有3种方法具有不同的第一个参数:
selfcls这些经典方法在Test下面的类中实现,包括常用方法:
class Test():
def __init__(self):
pass
def instance_mthd(self):
print("Instance method.")
@classmethod
def class_mthd(cls):
print("Class method.")
@staticmethod
def static_mthd():
print("Static method.")
def unknown_mthd():
# No decoration --> instance method, but
# No self (or cls) --> static method, so ... (?)
print("Unknown method.")
Run Code Online (Sandbox Code Playgroud)
在Python 3中,unknown_mthd可以安全地调用它,但它在Python 2中引发了一个错误:
>>> t = Test()
>>> # Python 3
>>> t.instance_mthd()
>>> Test.class_mthd()
>>> t.static_mthd()
>>> Test.unknown_mthd()
Instance method.
Class …Run Code Online (Sandbox Code Playgroud) 我有一些python代码包含如下所示的单元测试:
class SunCalcTestCases(unittest.TestCase):
"""Tests for `suncalc.py`."""
def near(val1, val2):
return abs(val1 - val2) < (margin or 1E-15)
def test_getPositions(self):
"""Get sun positions correctly"""
sunPos = suncalc.getPosition(self.date, self.lat, self.lng)
az = sunPos["azimuth"]
res = self.near(az, -2.5003175907168385)
Run Code Online (Sandbox Code Playgroud)
但是当我运行这个时,我得到错误:
Traceback (most recent call last):
File "test.py", line 64, in test_getPositions
res = self.near(az, -2.5003175907168385)
TypeError: near() takes exactly 2 arguments (3 given)
Run Code Online (Sandbox Code Playgroud)
我是python的新手,所以我很抱歉,如果我在这里遗漏了一些东西,但据我所知,我在调用函数时只传递了两个参数: self.near(az, -2.5003175907168385)
谁能告诉我为什么它认为我传递了3个参数?
python ×6
methods ×2
class-method ×1
coding-style ×1
decorator ×1
module ×1
oop ×1
python-2.7 ×1
singleton ×1