我试图创建一些装饰器,允许在实例化时装饰类成员,因为我想要一些装饰的实例和其他不是。
在下面的示例中,将once
装饰器应用于SomeClass
实例的预期结果是,当调用some_func
时,调用other_func
会打印一条消息而不是调用原始函数。
#!/usr/bin/env python
import functools
def some_once(func):
@functools.wraps(func)
def wrapped(self, *args, **kwargs):
if not self._new_attr:
print("don't have new attr yet")
func(self, *args, **kwargs)
self._new_attr = True
return wrapped
def other_once(func):
@functools.wraps(func)
def wrapped(self, *args, **kwargs):
if self._new_attr:
print("We have a new attr")
else:
func(self, *args, **kwargs)
return wrapped
def once(cls):
setattr(cls, "_new_attr", False)
setattr(cls, "some_func", some_once(cls.some_func))
setattr(cls, "other_func", other_once(cls.other_func))
return cls
class SomeClass:
def some_func(self, parameter):
return "The parameter is " + str(parameter)
def other_func(self, parameter):
return "The other parameter is " + str(parameter)
if __name__ == '__main__':
a = SomeClass()
print(dir(a))
print(a.some_func("p1"))
print(a.other_func("p2"))
b = once(SomeClass())
print(dir(b))
print(b.some_func("p3"))
print(b.other_func("p4"))
结果的问题在于,不是查看self._new_attr
,而是查看string._new_attr
,而字符串是函数的参数。我对这里的错误感到困惑。
答案 0 :(得分:1)
不要装饰实例。做一个新的装饰课。
更改此行:
private double Distance(double lat1, double lon1, double lat2, double lon2, int unit)
{
double theta = lon1 - lon2;
double dist = Math.Sin(Deg2rad(lat1)) * Math.Sin(Deg2rad(lat2)) + Math.Cos(Deg2rad(lat1)) * Math.Cos(Deg2rad(lat2)) * Math.Cos(Deg2rad(theta));
dist = Math.Acos(dist);
dist = Rad2deg(dist);
dist = dist * 60 * 1.1515;
if (unit == GeoFence.RadiusUnits.Kilometers.GetHashCode())
{
dist = dist * 1.609344; //kilometers
}
else if (unit == GeoFence.RadiusUnits.Feet.GetHashCode())
{
//Here I need to calculate distance in feet
}
return (dist); //By default the distance is in statute miles
}
成:
b = once(SomeClass())
应该做的伎俩。 b = once(SomeClass)()
为您提供了一个新的装饰类。在下一步中创建一个实例。