"data_source_type"및 "data_source_path"라는 속성이있는 간단한 "DataSource"클래스를 작성하려고합니다. "data_source_type"이 ENUM이고 "data_source_path"가 문자열 인 경우 "data_source_type"에 따라 "ValidFilePath"또는 "ValidHttpURL"과 같은 적절한 유효성 검사를 "data_source_path"로 설정하려고합니다."Python 설명자"를 사용하는 조건부 동적 유효성 검사기
IF-ELSE를 작성하고 스파게티 데이터 소스 클래스를 사용하고 싶지는 않지만 "Python 설명자"또는 SRP (Single Responsibility Principle)를 고려하고 기능 프로그래밍을 지원하는 기타 우아한 Python 구문을 활용하고 싶습니다. 구성.
data_source.py 줄 번호 51
1 import re
2 from enum import Enum
3 import os
4
5
6 class ValidFilePath(object):
7 def __set__(self, obj, val):
8 if not os.path.exists():
9 raise ValueError("Please enter a valid file path")
10 self.__url = val
11
12 def __get__(self, obj, objtype):
13 return self.__url
14
15
16 class ValidHttpURL(object):
17 def __set__(self, obj, val):
18 if (val is None or re.compile(
19 r'^https?://' # http:// or https://
20 r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain...
21 r'localhost|' # localhost...
22 r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
23 r'(?::\d+)?' # optional port
24 r'(?:/?|[/?]\S+)$', re.IGNORECASE).search(val) is None):
25 raise ValueError("Please set an valid HTTP(S) URL")
26 self.__url = val
27
28 def __get__(self, obj, objtype):
29 return self.__url
30
31
32 class DataSourceType(Enum):
33 HTTP = 100,
34 LOCAL_FILE = 200,
35 HDFS_FILE = 300
36
37
38 class ValidDataSourceType(object):
39 def __set__(self, obj, val):
40 if val is None or not DataSourceType.__contains__(DataSourceType[val]):
41 raise ValueError("Please set a valid Data Source Type Enum, "
42 " possible values are -> ", [e.name for e in DataSourceType])
43 self.__data_source_type = DataSourceType[val]
44
45 def __get__(self, obj, objtype):
46 return self.__data_source_type
47
48
49 class DataSource(object):
50 data_source_type = ValidDataSourceType()
51 data_source_path = ValidHttpURL()
나는 "data_source_type는"
예상에 따라 적절한 검증 설명을 설정할 지금은 뒀다 "ValidHttpURL"의 등 행동
ds1 = DataSource()
ds1.data_source_type = 'HTTP'
ds1.data_source_path = 'http://www.google.com'
ds2 = DataSource()
ds2.data_source_type = 'LOCAL_FILE'
ds2.data_source_path = '/var/www/index.html'
print("All is well")
실제 행동
01 23,516,ds1 = DataSource()
ds1.data_source_type = 'HTTP'
ds1.data_source_path = 'http://www.google.com'
ds2 = DataSource()
ds2.data_source_type = 'LOCAL_FILE'
ds2.data_source_path = '/var/www/index.html'
**ValueError: Please set an valid HTTP(S) URL**
*** 업데이트] 답변의 **** 그래서
1 import os
2 import re
3 from enum import Enum
4 from weakref import WeakKeyDictionary
5
6
7 def valid_file_path(value):
8 if not os.path.exists(value):
9 raise ValueError(value, " is not present. Please make sure the file exists")
10 return value
11
12
13 def valid_http_url(value):
14 if (value is None or re.compile(
15 r'^https?://' # http:// or https://
16 r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain...
17 r'localhost|' # localhost...
18 r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
19 r'(?::\d+)?' # optional port
20 r'(?:/?|[/?]\S+)$', re.IGNORECASE).search(value) is None):
21 raise ValueError("Please set an valid HTTP(S) URL")
22 return value
23
24
25 class DataSourceType(Enum):
26 NOT_DEFINED = (0, None)
27 HTTP = (100, valid_http_url)
28 LOCAL_FILE = (200, valid_file_path)
29
30 def __init__(self, enum_id, enum_validator):
31 self._id = enum_id
32 self._validator = enum_validator
33
34 @property
35 def validator(self):
36 return self._validator
37
38
39 class ValidDataSourceType(object):
40 def __init__(self):
41 self.default = DataSourceType.NOT_DEFINED
42 self.values = WeakKeyDictionary()
43
44 def __get__(self, instance, owner):
45 return self.values.get(instance, self.default)
46
47 def __set__(self, instance, value):
48 if value is None or not DataSourceType.__contains__(DataSourceType[value]):
49 raise ValueError("Please set a valid Data Source Type Enum, "
50 " possible values are -> ", [e.name for e in DataSourceType])
51 self.values[instance] = DataSourceType[value]
52
53 def __delete__(self, instance):
54 del self.values[instance]
55
56
57 class ValidDataSourcePath(object):
58 def __init__(self, default_data_source_type_field='data_source_type'):
59 self._default = ''
60 self._default_data_source_type_field = default_data_source_type_field
61 self.values = WeakKeyDictionary()
62
63 def __get__(self, instance, owner):
64 return self.values.get(instance, self._default)
65
66 def __set__(self, instance, *value):
67 data_source_type_field = self._default_data_source_type_field
68 value_to_set = None
69
70 if value and len(value) == 1 and isinstance(value[0], str): # user sent only the value
71 value_to_set = value[0]
72 if value and len(value) == 1 and isinstance(value[0], tuple): # user sent the value , and the validation field
73 value_to_set = value[0][0]
74 data_source_type_field = value[0][1]
75
76 _data_source_type = getattr(instance, data_source_type_field, None)
77 if not _data_source_type:
78 raise ValueError(" Valid source path depends on ValidDataSourceType , "
79 " please make sure you have an attribute named ValidDataSourceType")
80 _data_source_type.validator(value_to_set)
81 self.values[instance] = value_to_set
82
83
84 class DataSource(object):
85 data_source_type = ValidDataSourceType()
86 data_source_path = ValidDataSourcePath()
87
88
89 class SomeOtherDomainModel(object):
90 data_source_type_ext = ValidDataSourceType()
91 data_source_path = ValidDataSourcePath()
92
93
94 print(" **************** Scenario 1 - Start **************** ")
95 ds1 = DataSource()
96 ds1.data_source_type = 'HTTP'
97 ds1.data_source_path = "http://www.google.com"
98 print(ds1.data_source_path)
99 print(" **************** Scenario 1 - End **************** ")
100
101 print(" **************** Scenario 2 - Start **************** ")
102 ds2 = SomeOtherDomainModel()
103 ds2.data_source_type_ext = 'HTTP'
104 ds2.data_source_path = ("http://www.yahoo.com", 'data_source_type_ext')
105 print(ds2.data_source_path)
106 print(" **************** Scenario 2 - Start **************** ")
내 대답의 기본 사항 (기회가있을 때 전체 답장을 게시합니다.) : 1) 원본 형식 개체에는 이름과 유효성 검사기가 포함되어야합니다. 열거 형은 Python (https://docs.python.org/3/library/enum.html#planet)에서이를 허용합니다. 2) 소스 경로를 소스 유형에 저장된 유효성 검사기를 통해 실행되는 간단한 특성으로 만듭니다. –
@ jacob-zimmerman 제안 사항은 있지만 문제는 62 번과 63 번 라인에서 업데이트합니다. 71 번 라인에서 ENUM의 설명자를 아직 생성하지 않았으므로이를 연결할 수 없습니다. – Manjesh
아니요, 대신 실제'@ 속성 '을 사용합니다 'data_source_type'입니다. 커스텀 서술자를 정말로 사용하고 싶다면'ValidDataSourcePath'가'obj'에'data_source_type'을 가지고 있다고 가정하고 그것을 자체적으로 저장하는 대신에 사용하십시오. 해커예요.하지만 다른 건 생각할 수 없어요. –