Похоже, вы пытаетесь передать свой MyWebViewClient
класс в качестве экземпляра в этой строке:
myWebView.setWebViewClient(MyWebViewClient);
может попробовать что-то вроде этого:
myWebView.setWebViewClient(new MyWebViewClient());
или [116 ]
MyWebViewClient myWebviewClientInstance = new MyWebViewClient();
myWebView.setWebViewClient(myWebviewClientInstance);
Полагаю, мне следует расширить этот ответ, теперь, когда я стал старше и мудрее и знаю, что происходит. Лучше поздно, чем никогда.
Вы можете добавить свойство к классу динамически. Но в этом загвоздка: вы должны добавить его в класс .
>>> class Foo(object):
... pass
...
>>> foo = Foo()
>>> foo.a = 3
>>> Foo.b = property(lambda self: self.a + 1)
>>> foo.b
4
Свойство
на самом деле является простой реализацией того, что называется дескриптором . Это объект, который обеспечивает настраиваемую обработку для данного атрибута в данном классе . Вроде как способ выделить огромное if
дерево из __ getattribute __
.
Когда я прошу foo.b
в примере выше, Python видит, что b
, определенный в классе, реализует протокол дескриптора - что просто означает, что это объект с __ get __
, __ set __
или __ delete __
метод. Дескриптор берет на себя ответственность за обработку этого атрибута, поэтому Python вызывает Foo.b .__ get __ (foo, Foo)
, и возвращаемое значение возвращается вам как значение атрибута. В случае свойства
каждый из этих методов просто вызывает fget
, fset
или fdel
, которые вы передали в property
конструктор.
Дескрипторы - это на самом деле способ Python раскрыть всю внутреннюю структуру своей объектно-ориентированной реализации. Фактически, есть другой тип дескриптора, даже более распространенный, чем свойство
.
>>> class Foo(object):
... def bar(self):
... pass
...
>>> Foo().bar
<bound method Foo.bar of <__main__.Foo object at 0x7f2a439d5dd0>>
>>> Foo().bar.__get__
<method-wrapper '__get__' of instancemethod object at 0x7f2a43a8a5a0>
Скромный метод - это просто еще один вид дескриптора. Его __ get __
указывает на вызывающий экземпляр в качестве первого аргумента; по сути, он делает это:
def __get__(self, instance, owner):
return functools.partial(self.function, instance)
В любом случае, Я подозреваю, что именно поэтому дескрипторы работают только с классами: они формализация того, что в первую очередь поддерживает классы. Они даже являются исключением из правил: вы, очевидно, можете назначать дескрипторы классу, а классы сами являются экземплярами типа
! Фактически, попытка прочитать Foo.b
по-прежнему вызывает свойство .__ get __
; это просто идиоматично, когда дескрипторы возвращаются при обращении к ним как атрибуты класса.
Я думаю, это здорово, что практически вся объектно-ориентированная система Python может быть выражена на Python. :)
О, и я написал многословный пост в блоге о дескрипторах некоторое время назад, если вам интересно.
Это даже исключение из правила: вы, очевидно, можете назначать дескрипторы классу, а классы сами являются экземплярами типа
! Фактически, попытка прочитать Foo.b
по-прежнему вызывает свойство .__ get __
; это просто идиоматично, когда дескрипторы возвращаются при обращении к ним как атрибуты класса.
Я думаю, это здорово, что практически вся объектно-ориентированная система Python может быть выражена на Python. :)
О, и я написал многословный пост в блоге о дескрипторах некоторое время назад, если вам интересно.
Это даже исключение из правила: вы, очевидно, можете назначать дескрипторы классу, а классы сами являются экземплярами типа
! Фактически, попытка прочитать Foo.b
по-прежнему вызывает свойство .__ get __
; это просто идиоматично, когда дескрипторы возвращаются при обращении к ним как атрибуты класса.
Я думаю, это довольно круто, что практически вся объектно-ориентированная система Python может быть выражена на Python. :)
О, и я написал многословный пост в блоге о дескрипторах некоторое время назад, если вам интересно.
Это просто идиоматично для дескрипторов, которые возвращаются при обращении к ним как атрибуты класса.Я думаю, это довольно круто, что практически вся объектно-ориентированная система Python может быть выражена на Python. :)
О, и я написал многословный пост в блоге о дескрипторах некоторое время назад, если вам интересно.
Это просто идиоматично, когда дескрипторы возвращаются при обращении к ним как атрибуты класса.Я думаю, это довольно круто, что практически вся объектно-ориентированная система Python может быть выражена на Python. :)
О, и я написал многословный пост в блоге о дескрипторах некоторое время назад, если вам интересно.
Вот решение что:
После того, как класс был определен, Вы просто делаете это для добавления свойства к нему динамично:
setattr(SomeClass, 'propertyName', property(getter, setter))
Вот полный пример, протестированный в Python 3:
#!/usr/bin/env python3
class Foo():
pass
def get_x(self):
return 3
def set_x(self, value):
print("set x on %s to %d" % (self, value))
setattr(Foo, 'x', property(get_x, set_x))
foo1 = Foo()
foo1.x = 12
print(foo1.x)
Единственный способ динамически присоединить свойство - создать новый класс и его экземпляр с вашим новым свойством.
class Holder: p = property(lambda x: vs[i], self.fn_readonly)
setattr(self, k, Holder().p)
Вы не можете добавить новое свойство ()
в экземпляр во время выполнения, потому что свойства являются дескрипторами данных. Вместо этого вы должны динамически создать новый класс или перегрузить __ getattribute __
, чтобы обрабатывать дескрипторы данных в экземплярах.
Не уверен, что я полностью понимаю вопрос, но вы можете изменить свойства экземпляра во время выполнения с помощью встроенного __ dict __
вашего class:
class C(object):
def __init__(self, ks, vs):
self.__dict__ = dict(zip(ks, vs))
if __name__ == "__main__":
ks = ['ab', 'cd']
vs = [12, 34]
c = C(ks, vs)
print(c.ab) # 12
Похоже, вы могли бы решить эту проблему гораздо проще с помощью namedtuple
, поскольку вы заранее знаете весь список полей.
from collections import namedtuple
Foo = namedtuple('Foo', ['bar', 'quux'])
foo = Foo(bar=13, quux=74)
print foo.bar, foo.quux
foo2 = Foo() # error
Если вам абсолютно необходимо напишите свой собственный сеттер, вам придется выполнять метапрограммирование на уровне класса; property ()
не работает с экземплярами.
Для этого не нужно использовать свойство. Просто переопределите __ setattr __
, чтобы они были доступны только для чтения.
class C(object):
def __init__(self, keys, values):
for (key, value) in zip(keys, values):
self.__dict__[key] = value
def __setattr__(self, name, value):
raise Exception("It is read only!")
Тада.
>>> c = C('abc', [1,2,3])
>>> c.a
1
>>> c.b
2
>>> c.c
3
>>> c.d
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'd'
>>> c.d = 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in __setattr__
Exception: It is read only!
>>> c.a = 'blah'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in __setattr__
Exception: It is read only!
Лучший способ добиться этого - определить __ slots __
. Таким образом, ваши экземпляры не могут иметь новые атрибуты.
ks = ['ab', 'cd']
vs = [12, 34]
class C(dict):
__slots__ = []
def __init__(self, ks, vs): self.update(zip(ks, vs))
def __getattr__(self, key): return self[key]
if __name__ == "__main__":
c = C(ks, vs)
print c.ab
Это печатает 12
c.ab = 33
Это дает: AttributeError: объект 'C' не имеет атрибута 'ab'
Я задал аналогичный вопрос в этом сообщении о переполнении стека , чтобы создать фабрику классов, которая создает простые типы. Результатом был этот ответ , в котором была рабочая версия фабрики классов. Вот отрывок ответа:
def Struct(*args, **kwargs):
def init(self, *iargs, **ikwargs):
for k,v in kwargs.items():
setattr(self, k, v)
for i in range(len(iargs)):
setattr(self, args[i], iargs[i])
for k,v in ikwargs.items():
setattr(self, k, v)
name = kwargs.pop("name", "MyStruct")
kwargs.update(dict((k, None) for k in args))
return type(name, (object,), {'__init__': init, '__slots__': kwargs.keys()})
>>> Person = Struct('fname', 'age')
>>> person1 = Person('Kevin', 25)
>>> person2 = Person(age=42, fname='Terry')
>>> person1.age += 10
>>> person2.age -= 10
>>> person1.fname, person1.age, person2.fname, person2.age
('Kevin', 35, 'Terry', 32)
>>>
Вы можете использовать некоторые варианты этого для создания значений по умолчанию, что и является вашей целью (в этом вопросе также есть ответ).
Цель состоит в том, чтобы создать фиктивный класс, который ведет себя как набор результатов db.
Так что вам нужен словарь, в котором вы можете написать ['b'] как ab?
Это просто:
class atdict(dict):
__getattr__= dict.__getitem__
__setattr__= dict.__setitem__
__delattr__= dict.__delitem__
Кажется, это работает (но см. Ниже):
class data(dict,object):
def __init__(self,*args,**argd):
dict.__init__(self,*args,**argd)
self.__dict__.update(self)
def __setattr__(self,name,value):
raise AttributeError,"Attribute '%s' of '%s' object cannot be set"%(name,self.__class__.__name__)
def __delattr__(self,name):
raise AttributeError,"Attribute '%s' of '%s' object cannot be deleted"%(name,self.__class__.__name__)
Если вам нужно более сложное поведение, не стесняйтесь редактировать свой ответ.
Вероятно, следующего будет больше. эффективное использование памяти для больших наборов данных:
class data(dict,object):
def __init__(self,*args,**argd):
dict.__init__(self,*args,**argd)
def __getattr__(self,name):
return self[name]
def __setattr__(self,name,value):
raise AttributeError,"Attribute '%s' of '%s' object cannot be set"%(name,self.__class__.__name__)
def __delattr__(self,name):
raise AttributeError,"Attribute '%s' of '%s' object cannot be deleted"%(name,self.__class__.__name__)