Tôi có một lớp đơn giản kéo dài thời gian để chấp nhận một chuỗi với từ bổ nghĩa giá trị (ví dụ: '10m' sẽ là 1024 * 1024 * 10)Tại sao Python gọi __str__ thay vì trả lại giá trị lâu
Tôi có __str__
chức năng mà in các giá trị ban đầu được thông qua năm (tức là nếu '10m' được thông qua tại, trở lại '10m')
vấn đề là khi tôi gọi một cái gì đó như:
>>> printf("%d" % Size('10m'))
tôi nhận được sau
SystemError: ../Objects/stringobject.c:4044: bad argument to internal function
Rõ ràng nếu tôi in "%s"
tôi nhận được '10m'
Vì vậy, câu hỏi là, kể từ khi tôi đang subclassing dài, tại sao cuộc gọi lớp __str__
khi nó phải được nhận được giá trị lâu.
BTW, thử nghiệm nhiều hơn một chút cho thấy rằng %x
và %f
sẽ in giá trị số nguyên gây nhầm lẫn cho tôi nhiều hơn. Tôi cũng đã thử thêm __format__
nhưng dường như chỉ được gọi khi số điện thoại "...".format()
được gọi.
EDIT # 1, Dưới đây là các mã:
class Size(long):
'''Represents a size reflected bytes. Subclass of long.
Size passed in must be in the formats <int> or "0x<int>" or "0x<int><unit>" or "<int><unit>" or "<int><unit><int><unit>....".
"0x<int><unit>0x<int><unit>" or similar numbers are not supported as is "<int><unit><int>"
b = bytes
s = sectors (512-byte)
k = kilobytes
m = megabytes
g = gigabytes
t = terabytes
'''
units = { 'b':1, 's':512, 'k':1024, 'm':1024 ** 2, 'g':1024 ** 3, 't':1024 ** 4 }
def __new__(cls, value):
'''Creates a Size object with the specified value.
Value can be a number or a string (optionally prefixed with '0x' or
postfixed with a type character). If using hex, the final character
will be treated as part of the value if it is a hex digit, regardless
of whether it is a valid unit character.
Examples:
Size(50)
Size("0x100s") # 256 sectors
Size("64")
Size("512k")
Size("0x1b") # this is 1b bytes, not 1 byte
'''
self = _new_unit_number(value, cls.units, long, cls)
return self
def __init__(self, value):
self._orig_value = value
def __str__(self):
print "calling str"
return str(self._orig_value) # Convert to str in case the object was created w/an int
def __format__(self, format_spec):
print "calling format"
print format_spec
try:
value = format(str(self), format_spec)
except ValueError:
value = format(int(self), format_spec)
return value
def _new_unit_number(value, unit_list, num_type, cls):
'''Converts a string of numbers followed by a unit character to the
requested numeric type (int or long for example).
'''
base = 10
start = 0
digits = string.digits
try:
if value[0:2] == '0x':
start = 2
base = 16
digits = string.hexdigits
if value[-1] in digits:
return num_type.__new__(cls, value[start:], base)
else:
try:
# Use a regex to split the parts of the unit
regex_string = '(\d+[%s])' % (''.join(unit_list.keys()))
parts = [x for x in re.split(regex_string, value[start:]) if x]
if len(parts) == 1:
return num_type.__new__(cls, num_type(value[start:-1], base) * unit_list[value[-1]])
else:
# Total up each part
# There's probably a better way to do this.
# This converts each unit to its base type, stores it in total,
# only to be converted back to the base type.
total = 0
for part in parts:
total += num_type(part[start:-1], base) * unit_list[part[-1]]
# Finally return the requested unit
return num_type.__new__(cls, total)
except KeyError:
raise ValueError("Invalid %s unit identifier: %s"
% (cls.__name__, unit_list[value[-1]]))
# not a string or empty, see if we can still use the class's constructor
except (TypeError, IndexError):
return num_type.__new__(cls, value)
'Kích thước' được xác định như thế nào? – Hyperboreus
Lưu ý rằng "m" là ký hiệu quốc tế cho đồng hồ, hoặc tiền tố cho 10^-3. Nếu bạn muốn 10^6, sử dụng M. Nếu bạn muốn 2^20, sử dụng Mi. –
Bạn đang nhận hàm 'printf()' trong Python 2.7 ở đâu? –