注意 此问题与Python 3 Enum
数据类型无关,它只是我使用的示例。 < / p>
使用PEP 3115 Python 3将__prepare__
1 方法添加到type
,以便在创建类时允许使用自定义命名空间。例如,新的Enum
数据类型使用__prepare__
来返回私有_EnumDict
的实例,以用作新的Enum
类&#39;命名空间。
但是,我已经看到了几个关于EnumMeta
的SO 2 被子类化的例子,在元类__new__
方法中为类创建了一个新的命名空间,而不是调用获取新命名空间的__prepare__
方法,而是使用type(clsdict)()
。这样做有风险吗?
1 __prepare__
的签名:
@classmethod
def __prepare__(metacls, cls, bases, **kwds):
和__new__
:
def __new__(metacls, cls, bases, clsdict, **kwds):
2 使用type(clsdict)
的示例:
class CountryCodeMeta(enum.EnumMeta):
def __new__(metacls, cls, bases, classdict):
data = classdict['data']
names = [(country['alpha-2'], int(country['country-code'])) for country in data]
--> temp = type(classdict)()
for name, value in names:
temp[name] = value
excluded = set(temp) | set(('data',))
temp.update(item for item in classdict.items() if item[0] not in excluded)
return super(CountryCodeMeta, metacls).__new__(metacls, cls, bases, temp)
答案 0 :(得分:8)
是的,存在风险。
通过调用__prepare__
而不是type(clsdict)()
来获取新命名空间至少有两个原因:
在Python 2 clsdict
上运行时dict
是__prepare__
,原始__prepare__
从未运行过(__prepare__
仅限Python 3) - 换句话说,如果type(clsdict)()
正在返回除正常字典之外的内容,__prepare__
将无法获得它。
使用clsdict
时,type(clsdict)()
上由__prepare__
设置的所有属性都不会设置;即如果clsdict.spam = 'eggs'
type(clsdict)()
spam
,则__prepare__()
将不具有type(clsdict)()
属性。请注意,这些属性位于名称空间本身以供元类使用,并且在名称空间中不可见。
总结一下:有充分的理由使用 //Binary search method.
public static void BinarySearch<T>(T[] data)
{
Binary_Search(data, Console.ReadLine(), Comparer<T>.Default);
}
来获取正确的类字典,而 //Binary search algorithm
public static int Binary_Search<T>(T[] data, T searchFor, IComparer<T>comparer)
{
int high, low, mid;
high = data.Length - 1;
low = 0;
//if the first element of the array is what I'm looking for then return that element.
if (data[0].Equals(searchFor))
return 0;
//else if highest element in the array is the item im looking for then return the element.
else if (data[high].Equals(searchFor))
return high;
else
{
//While low point is lower than or equal with high point set the mid point to be in the middle of the highest and lowers point.
while (low <= high)
{
mid = (high + low) / 2;
//Compare mid point to the item searched, if the difference is 0 it means the item is there, return the element.
if (comparer.Compare(data[mid], searchFor) == 0)
return mid;
//Else if the difference between mid point and searched item is bigger than 0, the searched item must be lower than mid point,
//set the new high point to be current mid -1;
else if (comparer.Compare(data[mid], searchFor) > 0)
high = mid - 1;
//Else (Current mid point is lower than the searched item) set the new low point to be the current mid point +1.
else
low = mid + 1;
}
return -1;
}
}
快捷方式则没有。