Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.226.187.225] |
|
Сообщ.
#1
,
|
|
|
shared - статические типы, которые выделяют память на все классы.
Допустим (псевдокод): abstract class Some { static array<int> a = []; static shared array<int> b = []; } class Any1 extends Some {} class Any2 extends Some {} Any1.a.push(1); Any2.a.count; // 0 Any1.b.push(1); Any2.b.count; // 1 Из примера видно: 1) переменная "а" своя для Any1 и своя для Any2. Это две разных области памяти и она создаётся при наследовании. 2) переменная "b" общая для Any1 и Any2. При обращении к этому полю - обращение происходит к одному и тому же полю. Вообще есть такие языки, где подобное существует? А если нет, то в чём причина отсутствия такого модификатора? Добавлено Верное замечание в скайповом чатике было, что в php статики как раз по-умолчанию общие для всех наследников, но с другой стороны нет способа выделить память под отдельного ребёночка Вариант только один (в случае php): protected static $a = []; // ******* public static function push($data) { if (!isset( self::$a[$cls = get_called_class()] )) { self::$a[$cls] = []; } self::$a[$cls][] = $data; } // в результате в памяти переменной $a получим что-то такое: $a = [ НАЗВАНИЕ_КЛАССА => [ ДАННЫЕ, ДАННЫЕ, и т.д. ] ]; |
Сообщ.
#2
,
|
|
|
Добро пожаловать в Python с его ссылочной семантикой
>>> class Base: ... a = [] ... >>> >>> class Any1(Base): ... pass ... >>> class Any2(Base): ... pass ... >>> Any1.a.append(10) >>> Any2.a [10] >>> Base.a [10] |
Сообщ.
#3
,
|
|
|
Я так понимаю метод (метод ведь?) "pass" как раз и реализует прямой доступ к "a = []"? В таком случае, как я понимаю, что бы реализовать оба поведения - придётся перегружать другую переменную в ребёнке?
Добавлено class Base: a = [] b = [] class Any1(Base): pass b = [] class Any2(Base): pass b = [] Any1.a.append(10) Any2.a.append(10) Any1.a # [20] Any2.a # [20] Base.a # [20] Any1.b.append(10) Any2.b.append(10) Any1.b # [10] Any2.b # [10] Base.b # [0] Верно? |
Сообщ.
#4
,
|
|
|
Цитата Serafim @ "pass" как раз и реализует прямой доступ к "a = []" Не, pass - это всего лишь намек Python, что никаких выражений в объявлении класса не будет. Цитата Serafim @ Верно? Похоже, что да. |
Сообщ.
#5
,
|
|
|
Цитата Мяут-Настоящий @ Похоже, что да. Но в таком случае опять же получаем проблему, только с другой стороны Добавлено Ну т.е. что бы реализовать конкретный статик - его надо объявлять явно, а это (при условии сложной логики, например ActiveRecord) - туча геммороя |
Сообщ.
#6
,
|
|
|
Цитата Serafim @ Вообще есть такие языки, где подобное существует? type some = class public a:TArray<integer>; public class var b:TArray<integer>; private class constructor Create; // тут можно настроить end; |
Сообщ.
#7
,
|
|
|
Цитата Serafim @ Ну т.е. что бы реализовать конкретный статик - его надо объявлять явно, а это (при условии сложной логики, например ActiveRecord) - туча геммороя Напиши классовый конструктор __new__ в базовом классе, который будет делать за всех дочек что нужно (я правда пока слабо втыкаю, что нужно ) |
Сообщ.
#8
,
|
|
|
Цитата Мяут-Настоящий @ (я правда пока слабо втыкаю, что нужно Давай ещё раз =) Я предлагал (и заодно спрашивал о наличии) модификатор local\shared для указания принадлежности статиков к одному классу, либо ко всем сразу (при наследовании). В первом случае - это будет удобно, ну например для реализации ActiveRecord, где коллекция инстансов модели N будет возвращаться только при обращении к N. Во втором - для реализации всяких регистри паттернов или просто для общения между классами через какой-нибудь мост. Как-то так =) class Some { local static var; // После наследования - этот статик окажется у всех классов свой shared static var; // После наследования - этот статик будет общим для всех детей } З.Ы. Shaggy, это дельфи? Я просто не совсем втыкаю что происходит у тебя в примере :3 Добавлено Цитата Мяут-Настоящий @ Напиши классовый конструктор __new__ в базовом классе эээ, классовый конструктор? Ты имеешь ввиду статический конструктор? |
Сообщ.
#9
,
|
|
|
Serafim, в Python классовые методы получают первым аргументом класс, а статические методы - нет. Тут скорее разница в терминологии
|
Сообщ.
#10
,
|
|
|
опять ничего не понял первый раз слышу о термине "классовых методов" =)
|
Сообщ.
#11
,
|
|
|
class A: @classmethod def method1(*args): print args @staticmethod def method2(*args): print args A.method1(10) A.method2(10) (<class __main__.A at 0x7f991f7fe1f0>, 10) (10,) Так понятнее? |
Сообщ.
#12
,
|
|
|
Если судить по примеру, то в первом случае это статический метод, принадлежащий непосредственно классу (или имеющий контекст класса, в котором был объявлен), а во втором - он просто висит в воздухе и имеет глобальный контекст, так?
|
Сообщ.
#13
,
|
|
|
Кстати, а какова польза от этих переменных-то?
Цитата Serafim @ ли судить по примеру, то в первом случае это статический метод, принадлежащий непосредственно классу (или имеющий контекст класса, в котором был объявлен), а во втором - он просто висит в воздухе и имеет глобальный контекст, так? Тут наверное надо бы дать ссылку на Лутца или другого автора книг по Python Serafim, Python - не отягощенный всякими высокими концепциями язык, и код работает как написано. Любой метод в Python принадлежит классу, даже такой: class A: def f(self): print 'a' a = A() A.f(a) # 1 a.f() # 2 Второй вызов - не более чем синтаксический сахар для первого (это называется bound method, если что). self - это аналог this. Отличие статических методов (с декоратором staticmethod), в том что второй вид вызовов (a.f()) приведет к такой же семантике вызова, что и первый (A.f()) Что касается контекста, то в Python опять же есть область видимости переменных, правила которой мне лень вспоминать |
Сообщ.
#14
,
|
|
|
Цитата Мяут-Настоящий @ Кстати, а какова польза от этих переменных-то? А я разве не привёл пример простой реализации чего-либо, если бы были подобные модификаторы? Цитата Мяут-Настоящий @ Второй вызов - не более чем синтаксический сахар для первого (это называется bound method, если что). self - это аналог this. Отличие статических методов (с декоратором staticmethod), в том что второй вид вызовов (a.f()) приведет к такой же семантике вызова, что и первый (A.f()) ясно =) |