Я изменил ответ , чтобы вы могли указать, в каком углу вы хотите быть круглым, и какой из них вы хотите быть резким. также работает на pre-lolipop Пример использования
:
только верхний правый и углы botton-right закруглены
Path path = RoundedRect(0, 0, fwidth , fheight , 5,5,
false, true, true, false);
canvas.drawPath(path,myPaint);
public static Path RoundedRect(
float left, float top, float right, float bottom, float rx, float ry,
boolean tl, boolean tr, boolean br, boolean bl
){
Path path = new Path();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
if (tr)
path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
else{
path.rLineTo(0, -ry);
path.rLineTo(-rx,0);
}
path.rLineTo(-widthMinusCorners, 0);
if (tl)
path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
else{
path.rLineTo(-rx, 0);
path.rLineTo(0,ry);
}
path.rLineTo(0, heightMinusCorners);
if (bl)
path.rQuadTo(0, ry, rx, ry);//bottom-left corner
else{
path.rLineTo(0, ry);
path.rLineTo(rx,0);
}
path.rLineTo(widthMinusCorners, 0);
if (br)
path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
else{
path.rLineTo(rx,0);
path.rLineTo(0, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
return path;
}
Когда вы выполняете
./t1.py
, вы выполняете файл t1.py
, но он не выполняется как модуль t1
. Он считается модулем __main__
. (Это то, что проверяет строка if __name__ == '__main__'
.) Это означает, что когда эта строка:
import t1
в t2.py
пытается импортировать t1
, Python начинает выполнение файла t1.py
снова , чтобы создать модуль t1
. Вы получаете две версии класса A
, одна из которых - __main__.A
, а другая - t1.A
. Модификация t1.A
ничего не делает для __main__.A
, потому что, хотя они получены из одного и того же кода в том же файле, они не являются тем же классом.
Это действительно два разных объекта (очень хорошо объясняется в ответе пользователя user2357112 ). Если вы хотите, чтобы t2
использовал один и тот же объект, вам нужно сообщить Python, что вы фактически импортируете тот же модуль, который импортирует t2
. Для этого импортируйте __main__
:
import __main__
def f():
__main__.A.flag = True
print(__main__.A.flag)
Да, я вижу, как это может быть немного запутанным, но в основном это вопрос пространств имен, а также различие в том, что пространство имен __main__
не считается частью списка импортированных модулей. Это позволяет файлу, являющемуся точкой выполнения (и, следовательно, занимая пространство имен __main__
), также импортироваться в качестве модуля. С другой стороны, если один и тот же модуль импортируется более одного раза, интерпретатор просто позволяет всем различным импортам указывать на одно и то же место в памяти
. Из-за этого в коде, который вы показываете выше, вы на самом деле имеют две разные версии A
: у вас есть __main__.A
, и у вас есть __main__.t2.t1.A
. Второй вопрос возникает из-за того, что __main__
импортирует t2
, который, в свою очередь, импортирует t1
в качестве модуля.
Когда вы запускаете t2.f()
, вы устанавливаете __main__.t2.t1.A.flag = True
, а затем печатаете Это. Впоследствии, когда вы вызываете print(A.flag)
, вы печатаете значение в __main__.A.flag
, которое никогда не менялось.
Надеюсь, что это по меньшей мере немного.
Друг Я всегда говорил, что информатика - экспериментальная наука. Давайте запустим отладчик.
Добавляю pdb.set_trace()
к исполнению, а t1.py
теперь выглядит так:
#!/usr/bin/python
import t2
class A:
flag = False
if __name__ == "__main__":
import pdb; pdb.set_trace()
t2.f()
print(A.flag)
И это то, что мы получаем:
$ python t1.py
> /Users/martin/git/temp/t1.py(9)<module>()
-> t2.f()
(Pdb) A
<class __main__.A at 0x10ec9ba78>
(Pdb) t2.t1.A
<class t1.A at 0x10ec9ba10>
(Pdb)
Обратите внимание, что A
имеют отдельные ячейки памяти.
__main__
, не вызывает такого поведения. Если циклический импорт всегда приводил к повторному выполнению реимпортируемых модулей, вы бы получили переполнение стека из-за бесконечного рекурсивного импорта. __main__
имеет решающее значение.
– user2357112
29 July 2016 в 03:48
__main__
по-разному. Я соответствующим образом отрегулирую свой ответ.
– Dr K
29 July 2016 в 04:04
Вы можете найти это сами:
#!/usr/bin/python
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug('t1 has started')
logger.debug('t2 is being imported')
import t2
logger.debug('A is being "compiled"')
class A:
flag = False
logger.debug('ID A: %r', id(A))
logger.debug('ID A.flag %r', id(A.flag))
logger.debug('What is __name__? %r', __name__)
if __name__ == "__main__":
logger.debug('__name__ was "__main__"')
logger.debug('Calling t2.f()')
t2.f()
logger.debug('t2.f() was called')
logger.debug('ID A.flag: %r', id(A.flag))
print(A.flag)
#!/usr/bin/python
import logging
logger = logging.getLogger(__name__)
logger.debug('t2 is being imported')
logger.debug('t2 is now importing t1')
import t1
def f():
logger.debug('f is being called')
t1.A.flag = True
logger.debug('ID t1: %r', id(t1))
logger.debug('ID t1.A: %r', id(t1.A))
logger.debug('ID t1.A.flag: %r', id(t1.A.flag))
print(t1.A.flag)
Я раскалываю это с комментариями
DEBUG:__main__:t1 has started
DEBUG:__main__:t2 is being imported
DEBUG:t2:t2 is being imported
DEBUG:t2:t2 is now importing t1
Как вы можете видеть, в первый раз (как отмечали другие) t1
на самом деле имеет имя __main__
. Он пытается импортировать t2
, но сразу t2
пытается импортировать t1
.
DEBUG:t1:t1 has started
DEBUG:t1:t2 is being imported
Вы можете видеть, что ни одно из операторов журнала t2
не запускается. Это потому, что Python кэширует импортированные модули, поэтому он сначала смотрит в кеш для t2
и говорит: «Ага, я уже импортировал этого парня, мне просто нужно вернуть его, вот и все!»
DEBUG:t1:A is being "compiled"
DEBUG:t1:ID A: 140377934341704
DEBUG:t1:ID A.flag 4312040768
DEBUG:t1:What is __name__? 't1'
Итак, вы заметите, что теперь он пробился через импорт t1
. И t2
DEBUG:t2:t2 is done being imported
Выполнение продолжается в __main__
t1
DEBUG:__main__:A is being "compiled"
DEBUG:__main__:ID A: 140377934344360
DEBUG:__main__:ID A.flag 4312040768
Обратите внимание, что id
для этого A
и A.flag
DEBUG:__main__:What is __name__? '__main__'
DEBUG:__main__:__name__ was "__main__"
DEBUG:__main__:Calling t2.f()
DEBUG:t2:f is being called
DEBUG:t2:ID t1: 4317998840
DEBUG:t2:ID t1.A: 140377934341704
DEBUG:t2:ID t1.A.flag: 4312040736
Обратите внимание, что эти id
s соответствуют t1.A
, а не __main__.A
s.
True
DEBUG:__main__:t2.f() was called
DEBUG:__main__:ID A.flag: 4312040768
False