Да, \
в строковых литералах Python обозначает начало escape-последовательности. На вашем пути у вас есть действительная двухсимвольная escape-последовательность \a
, которая сжимается на символ one , который является ASCII Bell :
>>> '\a'
'\x07'
>>> len('\a')
1
>>> 'C:\meshes\as'
'C:\\meshes\x07s'
>>> print('C:\meshes\as')
C:\meshess
Другие общие escape-последовательности включают в себя \t
(вкладка), \n
(строка), \r
(возврат каретки):
>>> list('C:\test')
['C', ':', '\t', 'e', 's', 't']
>>> list('C:\nest')
['C', ':', '\n', 'e', 's', 't']
>>> list('C:\rest')
['C', ':', '\r', 'e', 's', 't']
Как вы можете видеть, во всех этих примерах обратная косая черта и следующий символ в литерале были сгруппированы вместе, чтобы сформировать единственный символ в финальной строке. Полный список управляющих последовательностей Python здесь здесь .
Существует множество способов борьбы с этим:
r
или R
: >>> r'C:\meshes\as'
'C:\\meshes\\as'
>>> print(r'C:\meshes\as')
C:\meshes\as
os.path.join
... >>> import os
>>> os.path.join('C:', os.sep, 'meshes', 'as')
'C:\\meshes\\as'
pathlib
модуль >>> from pathlib import Path
>>> Path('C:', '/', 'meshes', 'as')
WindowsPath('C:/meshes/as')
Вы можете сделать это, переопределив метод -(void)description
.
Пример: предположим, что у нас есть простой класс Car
.
@interface Car : NSObject
@property (copy, nonatomic) NSString *model;
@property (copy, nonatomic) NSString *make;
@property (strong, nonatomic) NSDate *registrationDate;
@property (assign, nonatomic) NSInteger mileage;
@property (assign, nonatomic) double fuelConsumption;
@end
@implementation
- (NSString*)description {
return [NSString stringWithFormat:@"<%@:%p %@>",
[self className],
self,
@{ @"model" : self.model,
@"make" : self.make,
@"registrationDate": self.registrationDate,
@"mileage" : @(self.mileage),
@"fuelConsumption" : @(self.fuelConsumption)
}];
}
@end
Полагая это в NSDictionary
, создайте очень приятный вывод в консоли.
С другой стороны, вы можете создать категорию в классе NSObject
и сделать что-то вроде этого:
- (NSString*)myDescriptionMethod {
NSMutableDictionary *dict = [NSMutableDictionary new];
unsigned int count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0; i < count; i++) {
const char *property = property_getName(properties[i]);
NSString *propertyString = [NSString stringWithCString:property encoding:[NSString defaultCStringEncoding]];
id obj = [self valueForKey:propertyString];
[dict setValue:obj forKey:propertyString];
}
free(properties);
return [NSString stringWithFormat:@"<%@ %p %@>",
[self class],
self,
dict];
}
Тогда вы избежите переопределения -(void)description
в ваших классах.
Получите его из здесь
Пример: -
+ (NSString *)description;
[NSString description];
Дает вам информацию о классе NSString.
Самый элегантный способ добиться того, что вы ищете в Objective-C с подклассами NSObject
, это переопределить метод NSObject
description
.
Например (если ваш класс имеет свойство, называемое propertyX):
-(NSString *)description
{
return [NSString stringWithFormat:@"<myCustomObject: %@, propertyX: %f, %f>",
[self objectID], [self propertyX].x, [self propertyX].y];
}
Реализация description
по умолчанию description
будет просто возвращать адрес памяти, указанный для объекта, например:
NSLog(@"%@", self);
< blockquote> 2015-06-15 14: 20: 30.123 AppName [...] myCustomObject: 0x000000>
blockquote>Однако, переопределив этот базовый метод класса, как показано выше, вы вы можете настроить это поведение, и журнал будет выглядеть следующим образом:
2015-06-15 14: 20: 30.123 AppName [...] myCustomObject: 0x000000 someProperty, Свойство: blah, blah>
blockquote>Существует хороший учебник, в котором обсуждаются следующие здесь .