Вы можете использовать lookaround.
/^abc(?!.*abc).*123.*(?<!xyz.*)xyz$/g
(я его не тестировал.)
Необходимо использовать @property
декоратор.
>>> class a(object):
... def __init__(self, x):
... self.x = x
... @property
... def xval(self):
... return self.x
...
>>> b = a(5)
>>> b.xval
5
>>> b.xval = 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
class C(object):
def __init__(self):
self.fullaccess = 0
self.__readonly = 22 # almost invisible to outside code...
# define a publicly visible, read-only version of '__readonly':
readonly = property(lambda self: self.__readonly)
def inc_readonly( self ):
self.__readonly += 1
c=C()
# prove regular attribute is RW...
print "c.fullaccess = %s" % c.fullaccess
c.fullaccess = 1234
print "c.fullaccess = %s" % c.fullaccess
# prove 'readonly' is a read-only attribute
print "c.readonly = %s" % c.readonly
try:
c.readonly = 3
except AttributeError:
print "Can't change c.readonly"
print "c.readonly = %s" % c.readonly
# change 'readonly' indirectly...
c.inc_readonly()
print "c.readonly = %s" % c.readonly
Это производит:
Python $./p.py
c.fullaccess = 0
c.fullaccess = 1234
c.readonly = 22
Не может изменить c.readonly
c.readonly = 22
c.readonly = 23
Мои пальцы жаждут смочь сказать
@readonly
self.readonly = 22
т.е. используйте декоратора на атрибуте. Это было бы настолько чисто...
Вы могли использовать метакласс, который автопереносит методы (или атрибуты класса), которые следуют соглашению о присвоении имен в свойства (бесстыдно взятый от Объединения Типов и Классов в Python 2.2:
class autoprop(type):
def __init__(cls, name, bases, dict):
super(autoprop, cls).__init__(name, bases, dict)
props = {}
for name in dict.keys():
if name.startswith("_get_") or name.startswith("_set_"):
props[name[5:]] = 1
for name in props.keys():
fget = getattr(cls, "_get_%s" % name, None)
fset = getattr(cls, "_set_%s" % name, None)
setattr(cls, name, property(fget, fset))
Это позволяет Вам использовать:
class A:
__metaclass__ = autosuprop
def _readonly(self):
return __x
Нет никакого реального способа сделать это. Существуют способы сделать это более 'трудным', но нет никакого понятия абсолютно скрытых, недоступных атрибутов класса.
Если человеку, использующему Ваш класс, нельзя доверять для следования документам API, то это - их собственная проблема. Защита людей от выполнения глупого материала просто означает, что они сделают намного более тщательно продуманный, сложный, и повреждение глупого материала, чтобы попытаться сделать независимо от того, что они не должны были делать во-первых.
Вот то, как:
class whatever(object):
def __init__(self, a, b, c, ...):
self.__foobar = 1
self.__blahblah = 2
foobar = property(lambda self: self.__foobar)
blahblah = property(lambda self: self.__blahblah)
(Принятие foobar
и blahblah
атрибуты, Вы хотите быть только для чтения.) Предварительное ожидание двух символов нижнего подчеркивания к названию атрибута эффективно скрывает его снаружи класса, таким образом, внутренние версии не будут доступны с внешней стороны. Это только работает на модернизированные классы, наследовавшиеся объекту, так как он зависит от property
.
С другой стороны... это - довольно глупая вещь сделать. Хранение частных переменных, кажется, навязчивая идея, которая прибывает из C++ и Java. Ваши пользователи должны использовать открытый интерфейс для Вашего класса, потому что он хорошо разработан, не потому что Вы вынуждаете их к.
Править: Похож на Kevin, уже отправил аналогичную версию.
Я знаю, что Уильям Келлер - безусловно самое чистое решение .. но вот кое-что, что я придумал ..
class readonly(object):
def __init__(self, attribute_name):
self.attribute_name = attribute_name
def __get__(self, instance, instance_type):
if instance != None:
return getattr(instance, self.attribute_name)
else:
raise AttributeError("class %s has no attribute %s" %
(instance_type.__name__, self.attribute_name))
def __set__(self, instance, value):
raise AttributeError("attribute %s is readonly" %
self.attribute_name)
А вот пример использования
class a(object):
def __init__(self, x):
self.x = x
xval = readonly("x")
К сожалению, это решение не может обрабатывать частные переменные (__ именованные переменные).