На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> "Расшаренные" статик-переменные и методы , shared static
    shared - статические типы, которые выделяют память на все классы.

    Допустим (псевдокод):
    ExpandedWrap disabled
      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):
    ExpandedWrap disabled
      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 = [
        НАЗВАНИЕ_КЛАССА => [
          ДАННЫЕ,
          ДАННЫЕ,
          и т.д.
        ]
      ];
      Добро пожаловать в Python с его ссылочной семантикой :D
      ExpandedWrap disabled
        >>> class Base:
        ...     a = []
        ...
        >>>
        >>> class Any1(Base):
        ...     pass
        ...
        >>> class Any2(Base):
        ...     pass
        ...
        >>> Any1.a.append(10)
        >>> Any2.a
        [10]
        >>> Base.a
        [10]
      Сообщение отредактировано: Мяут-Настоящий -
        Я так понимаю метод (метод ведь?) "pass" как раз и реализует прямой доступ к "a = []"? В таком случае, как я понимаю, что бы реализовать оба поведения - придётся перегружать другую переменную в ребёнке?

        Добавлено
        ExpandedWrap disabled
          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]


        Верно?
        Сообщение отредактировано: Serafim -
          Цитата Serafim @
          "pass" как раз и реализует прямой доступ к "a = []"

          Не, pass - это всего лишь намек Python, что никаких выражений в объявлении класса не будет.
          Цитата Serafim @
          Верно?

          Похоже, что да.
            Цитата Мяут-Настоящий @
            Похоже, что да.

            Но в таком случае опять же получаем проблему, только с другой стороны :)

            Добавлено
            Ну т.е. что бы реализовать конкретный статик - его надо объявлять явно, а это (при условии сложной логики, например ActiveRecord) - туча геммороя
              Цитата Serafim @
              Вообще есть такие языки, где подобное существует?

              ExpandedWrap disabled
                type
                  some = class
                    public
                      a:TArray<integer>;
                    public class var
                      b:TArray<integer>;
                    private
                      class constructor Create; // тут можно настроить
                  end;

              :)
                Цитата Serafim @
                Ну т.е. что бы реализовать конкретный статик - его надо объявлять явно, а это (при условии сложной логики, например ActiveRecord) - туча геммороя

                Напиши классовый конструктор __new__ в базовом классе, который будет делать за всех дочек что нужно (я правда пока слабо втыкаю, что нужно :) )
                  Цитата Мяут-Настоящий @
                  (я правда пока слабо втыкаю, что нужно

                  Давай ещё раз =)

                  Я предлагал (и заодно спрашивал о наличии) модификатор local\shared для указания принадлежности статиков к одному классу, либо ко всем сразу (при наследовании).

                  В первом случае - это будет удобно, ну например для реализации ActiveRecord, где коллекция инстансов модели N будет возвращаться только при обращении к N. Во втором - для реализации всяких регистри паттернов или просто для общения между классами через какой-нибудь мост.

                  Как-то так =)
                  ExpandedWrap disabled
                    class Some
                    {
                      local static var;  // После наследования - этот статик окажется у всех классов свой
                      shared static var; // После наследования - этот статик будет общим для всех детей
                    }



                  З.Ы. Shaggy, это дельфи? Я просто не совсем втыкаю что происходит у тебя в примере :3


                  Добавлено
                  Цитата Мяут-Настоящий @
                  Напиши классовый конструктор __new__ в базовом классе

                  эээ, классовый конструктор? Ты имеешь ввиду статический конструктор?
                  Сообщение отредактировано: Serafim -
                    Serafim, в Python классовые методы получают первым аргументом класс, а статические методы - нет. Тут скорее разница в терминологии :)
                      :wacko: опять ничего не понял :D первый раз слышу о термине "классовых методов" =)
                        ExpandedWrap disabled
                          class A:
                                  @classmethod
                                  def method1(*args):
                                          print args
                           
                                  @staticmethod
                                  def method2(*args):
                                          print args
                           
                          A.method1(10)
                          A.method2(10)


                        ExpandedWrap disabled
                          (<class __main__.A at 0x7f991f7fe1f0>, 10)
                          (10,)


                        Так понятнее? ;)
                          Если судить по примеру, то в первом случае это статический метод, принадлежащий непосредственно классу (или имеющий контекст класса, в котором был объявлен), а во втором - он просто висит в воздухе и имеет глобальный контекст, так?
                            Кстати, а какова польза от этих переменных-то?

                            Цитата Serafim @
                            ли судить по примеру, то в первом случае это статический метод, принадлежащий непосредственно классу (или имеющий контекст класса, в котором был объявлен), а во втором - он просто висит в воздухе и имеет глобальный контекст, так?

                            Тут наверное надо бы дать ссылку на Лутца или другого автора книг по Python :)
                            Serafim, Python - не отягощенный всякими высокими концепциями язык, и код работает как написано. Любой метод в Python принадлежит классу, даже такой:
                            ExpandedWrap disabled
                              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 опять же есть область видимости переменных, правила которой мне лень вспоминать :)
                              Цитата Мяут-Настоящий @
                              Кстати, а какова польза от этих переменных-то?

                              А я разве не привёл пример простой реализации чего-либо, если бы были подобные модификаторы? :huh:

                              Цитата Мяут-Настоящий @
                              Второй вызов - не более чем синтаксический сахар для первого (это называется bound method, если что). self - это аналог this.
                              Отличие статических методов (с декоратором staticmethod), в том что второй вид вызовов (a.f()) приведет к такой же семантике вызова, что и первый (A.f())

                              ясно =)
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0806 ]   [ 15 queries used ]   [ Generated: 28.04.24, 05:13 GMT ]