PHP свойства только для чтения?

В настоящее время вы присоединяетесь к своим фреймам данных следующим образом:

(((td1 + td2) + td3) + td4)

На каждом этапе вы объединяете огромный фрейм данных с небольшим фреймом данных, что приводит к копированию на каждом шаге и большому расходу памяти. Я бы предложил объединить их так:

(td1 + td2) + (td3 + td4)

Идея состоит в том, чтобы итеративно объединять пары примерно одинакового размера, пока не останется один результат. Вот прототип:

def pairwise_reduce(op, x):
    while len(x) > 1:
        v = [op(i, j) for i, j in zip(x[::2], x[1::2])]
        if len(x) > 1 and len(x) % 2 == 1:
            v[-1] = op(v[-1], x[-1])
        x = v
    return x[0]

result = pairwise_reduce(DataFrame.unionAll, df_list)

Вы увидите, как это имеет огромное значение для списков Python.

from functools import reduce 
from operator import add

x = [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10, 11, 12]] * 1000

%timeit sum(x, [])
%timeit reduce(add, x)
%timeit pairwise_reduce(add, x)

64.2 ms ± 606 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
66.3 ms ± 679 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
970 µs ± 9.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

sum(x, []) == reduce(add, x) == pairwise_reduce(add, x)
# True
58
задан hakre 12 October 2012 в 09:20
поделиться

4 ответа

Можно сделать это как это:

class Example {
    private $__readOnly = 'hello world';
    function __get($name) {
        if($name === 'readOnly')
            return $this->__readOnly;
        user_error("Invalid property: " . __CLASS__ . "->$name");
    }
    function __set($name, $value) {
        user_error("Can't set property: " . __CLASS__ . "->$name");
    }
}

Только используйте это при реальной необходимости в нем - это медленнее, чем нормальный доступ свойства. Для PHP, лучше принимать политику только использования методов установщика изменить свойство с внешней стороны.

43
ответ дан too much php 24 November 2019 в 19:08
поделиться
Class PropertyExample {

        private $m_value;

        public function Value() {
            $args = func_get_args();
            return $this->getSet($this->m_value, $args);
        }

        protected function _getSet(&$property, $args){
            switch (sizeOf($args)){
                case 0:
                    return $property;
                case 1:
                    $property = $args[0];
                    break;  
                default:
                    $backtrace = debug_backtrace();
                    throw new Exception($backtrace[2]['function'] . ' accepts either 0 or 1 parameters');
            }
        }


}

Вот как я имею дело с получением / настройкой моих свойств, если вы хотите сделать Value () доступным только для чтения ... тогда вы просто просто сделаете это вместо этого:

    return $this->m_value;

Где как функция Value () сейчас либо получит, либо установит.

-1
ответ дан 24 November 2019 в 19:08
поделиться

Я вижу, вы уже получили свой ответ, но для тех, кто все еще ищет:

Просто объявите все переменные "только для чтения" как закрытые или защищенные и используйте волшебный метод __get () следующим образом:

/**
 * This is used to fetch readonly variables, you can not read the registry
 * instance reference through here.
 * 
 * @param string $var
 * @return bool|string|array
 */
public function __get($var)
{
    return ($var != "instance" && isset($this->$var)) ? $this->$var : false;
}

Как видите, я также защитил переменную экземпляра $ this->, поскольку этот метод позволяет пользователям читать все объявленные переменные. Чтобы заблокировать несколько переменных, используйте массив с in_array ().

5
ответ дан 24 November 2019 в 19:08
поделиться

Но частные свойства, предоставляемые только с помощью __get (), не видны функциям, которые перечисляют элементы объекта - например, json_encode ().

Я регулярно передаю объекты PHP в Javascript с помощью json_encode ( ), поскольку это хороший способ передать сложные структуры с большим количеством данных, заполненных из базы данных. Я должен использовать общедоступные свойства в этих объектах, чтобы эти данные передавались в Javascript, который их использует, но это означает, что эти свойства должны быть общедоступными (и, следовательно, есть риск того, что другой программист не на той же длине волны (или, возможно, я после плохой ночи) мог бы изменить их напрямую). Если я сделаю их закрытыми и использую __get () и __set (), то json_encode () их не увидит.

Разве не было бы неплохо иметь ключевое слово доступности "только для чтения"?

12
ответ дан 24 November 2019 в 19:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: