Так как мой tableView
полон всевозможных вставок, это было единственное, что сработало:
Swift 3
if tableView.numberOfSections > 0 && tableView.numberOfRows(inSection: 0) > 0 {
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
Swift 2
if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}
Хорошо, поэтому я не понимал, что вы довольны статической копией аргументов, пока я не закончил половину своего решения. Но я решил не тратить зря, так что все равно вот оно. Отличие от других решений в том, что оно фактически получит атрибуты от родителя, даже если они обновлены.
_marker = object()
class Parent(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
class Child(Parent):
_inherited = ['x', 'y', 'z']
def __init__(self, parent):
self._parent = parent
self.a = "not got from dad"
def __getattr__(self, name, default=_marker):
if name in self._inherited:
# Get it from papa:
try:
return getattr(self._parent, name)
except AttributeError:
if default is _marker:
raise
return default
if name not in self.__dict__:
raise AttributeError(name)
return self.__dict__[name]
Теперь, если мы сделаем это:
>>> A = Parent('gotten', 'from', 'dad')
>>> B = Child(A)
>>> print "a, b and c is", B.x, B.y, B.z
a, b and c is gotten from dad
>>> print "But x is", B.a
But x is not got from dad
>>> A.x = "updated!"
>>> print "And the child also gets", B.x
And the child also gets updated!
>>> print B.doesnotexist
Traceback (most recent call last):
File "acq.py", line 44, in <module>
print B.doesnotexist
File "acq.py", line 32, in __getattr__
raise AttributeError(name)
AttributeError: doesnotexist
Для более общей версии этого, посмотрите http: //pypi.python.org/pypi/Acquisition пакет. Фактически, в некоторых случаях это кровавое решение.
Спасибо, ребята, быстро! Сначала я прочитал комментарий Алекса и переписал __ init __
ребенка как
def __init__(self, *args, **kwds):
if len(args) == 1 and str(type(args[0])) == "<class '__main__.Parent'>":
new_args = [args[0].x, args[0].y, args[0].z]
super(Child, self).__init__(*new_args, **kwds)
else:
super(Child, self).__init__(*args, **kwds)
, что очень похоже на то, что предлагал abhinavg (как я только что узнал). И это работает. Только его строка и строка ars
if len(args) == 1 and isinstance(args[0], Parent):
чище моей.
Еще раз спасибо !!
Вы не определяете конструктор (init) для Child, поэтому вызывается конструктор Parent, ожидая 4 аргумента, в то время как только 2 передаются (из new). Вот один из способов добиться желаемого:
class Child(Parent):
def __init__(self, *args, **kwargs):
if len(args) == 1 and isinstance(args[0], Parent):
Parent.__init__(self, args[0].x, args[0].y, args[0].z)
else:
# do something else
Как только __ new __
в классе Child
возвращает экземпляр Child
, Child .__ init __
будет вызывается (с теми же аргументами __ new __
) в этом экземпляре - и, по-видимому, он просто наследует Parent .__ init __
, что не подходит для вызова только с одним аргументом ( other Parent
, A
).
Если нет другого способа создать Child
, вы можете определить Child .__ init __
, который принимает либо один аргумент (который игнорируется), либо три (в этом случае он вызывает Parent .__ init __
). Но проще отказаться от __ new __
и иметь всю логику в Child .__ init __
, просто вызвав Parent. __init __
соответственно!
Чтобы сделать это конкретным с помощью примера кода:
class Parent(object):
def __init__(self, x, y, z):
print "INITIALIZING PARENT"
self.x = x
self.y = y
self.z = z
def __str__(self):
return "%s(%r, %r, %r)" % (self.__class__.__name__,
self.x, self.y, self.z)
class Child(Parent):
_sentinel = object()
def __init__(self, x, y=_sentinel, z=_sentinel):
print "INITIALIZING CHILD"
if y is self._sentinel and z is self._sentinel:
print "HIJACKING"
z = x.z; y = x.y; x = x.x
Parent.__init__(self, x, y, z)
print "CHILD IS DONE!"
p0 = Parent(1, 2, 3)
print p0
c1 = Child(p0)
print c1
c2 = Child(4, 5, 6)
print c2