Python 함수 속성 - 사용 및 남용
이 기능을 아는 사람은 많지 않지만 Python의 함수(및 메서드)는 속성을 가질 수 있습니다.보기:
>>> def foo(x):
... pass
...
>>> foo.score = 10
>>> dir(foo)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'score']
>>> foo.score
10
>>> foo.score += 1
>>> foo.score
11
Python에서 이 기능의 사용 및 남용은 무엇입니까?PLY가 docstring을 사용하여 구문 규칙을 메서드에 연관짓는 것이 좋은 용도 중 하나입니다.하지만 커스텀 속성은 어떨까요?그것들을 사용하는 좋은 이유가 있나요?
저는 보통 주석의 저장소로 함수 속성을 사용합니다.C# 스타일(특정 메서드가 웹 서비스인터페이스의 일부임을 나타냄)로 쓰려고 합니다.
class Foo(WebService):
@webmethod
def bar(self, arg1, arg2):
...
그럼 내가 정의할 수 있어
def webmethod(func):
func.is_webmethod = True
return func
그런 다음 웹 서비스 콜이 도착하면 메서드를 검색하여 기본 함수에 is_webmethod 속성이 있는지 확인하고(실제 값은 관련이 없음), 메서드가 존재하지 않거나 웹을 통해 호출되는 것을 의도하지 않으면 서비스를 거부합니다.
함수의 정적 변수로 사용해 왔습니다.예를 들어, 다음과 같은 C 코드가 지정됩니다.
int fn(int i)
{
static f = 1;
f += i;
return f;
}
Python에서도 비슷한 기능을 구현할 수 있습니다.
def fn(i):
fn.f += i
return fn.f
fn.f = 1
이것은 분명히 '학대'의 끝에 속할 것이다.
JavaScript 방식으로 객체를 수행할 수 있습니다.말이 되지는 않지만 효과가 있습니다;)
>>> def FakeObject():
... def test():
... print "foo"
... FakeObject.test = test
... return FakeObject
>>> x = FakeObject()
>>> x.test()
foo
사용 빈도가 낮지만 매우 편리합니다.
def log(msg):
log.logfile.write(msg)
이제 사용할 수 있습니다.log
모듈 전체에 걸쳐 단순히 설정만으로 출력을 리다이렉트 할 수 있습니다.log.logfile
그 밖에도 여러 가지 방법이 있습니다만, 이것은 가볍고 매우 간단합니다.처음 했을 때는 이상한 냄새가 났지만 글로벌한 냄새가 나는 것보다 더 좋은 냄새가 난다는 걸 알게 됐어요logfile
변수.
함수 속성을 사용하여 코드와 관련 데이터를 함께 묶는 경량 폐쇄를 작성할 수 있습니다.
#!/usr/bin/env python
SW_DELTA = 0
SW_MARK = 1
SW_BASE = 2
def stopwatch():
import time
def _sw( action = SW_DELTA ):
if action == SW_DELTA:
return time.time() - _sw._time
elif action == SW_MARK:
_sw._time = time.time()
return _sw._time
elif action == SW_BASE:
return _sw._time
else:
raise NotImplementedError
_sw._time = time.time() # time of creation
return _sw
# test code
sw=stopwatch()
sw2=stopwatch()
import os
os.system("sleep 1")
print sw() # defaults to "SW_DELTA"
sw( SW_MARK )
os.system("sleep 2")
print sw()
print sw2()
1.00934004784
2.00644397736
3.01593494415
기능 속성을 쉽게 설정할 수 있도록 도우미 데코레이터를 만들었습니다.
def with_attrs(**func_attrs):
"""Set attributes in the decorated function, at definition time.
Only accepts keyword arguments.
E.g.:
@with_attrs(counter=0, something='boing')
def count_it():
count_it.counter += 1
print count_it.counter
print count_it.something
# Out:
# >>> 0
# >>> 'boing'
"""
def attr_decorator(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
return fn(*args, **kwargs)
for attr, value in func_attrs.iteritems():
setattr(wrapper, attr, value)
return wrapper
return attr_decorator
사용 사례는 팩토리 컬렉션을 생성하고 함수 메타 수준에서 생성할 수 있는 데이터 유형을 쿼리하는 것입니다.
를매매매매 ( )
@with_attrs(datatype=list)
def factory1():
return [1, 2, 3]
@with_attrs(datatype=SomeClass)
def factory2():
return SomeClass()
factories = [factory1, factory2]
def create(datatype):
for f in factories:
if f.datatype == datatype:
return f()
return None
함수의 속성을 사용하여 이미 계산된 값을 캐싱할 수 있습니다.또, 이 어프로치를 일반화하는 범용 데코레이터를 사용할 수도 있습니다.동시성 문제 및 이러한 기능의 부작용에 유의하십시오!
나는 항상 이것이 가능한 유일한 이유는 문서 문자열이나 다른 것들을 넣을 수 있는 논리적인 장소가 있기 때문이라고 생각했다.만약 내가 어떤 생산 코드에 사용한다면, 누가 읽는지 혼란스러울 거라는 걸 알아.
언급URL : https://stackoverflow.com/questions/338101/python-function-attributes-uses-and-abuses
'source' 카테고리의 다른 글
MariaDB 10.1의 DELETE 구문 오류 원인을 알 수 없습니다. (0) | 2022.11.24 |
---|---|
GD vs ImageMagick vs Gmagick for jpg? (0) | 2022.11.24 |
경고: [bootstrap]클래스 경로가 -source 1.5와 함께 설정되지 않음 (0) | 2022.11.24 |
AWS RDS 인스턴스 업그레이드 중단 시간 (0) | 2022.11.24 |
MySQL에 금전적 가치를 저장하기에 최적의 데이터 유형 (0) | 2022.11.24 |