Sürüm 26.8'de Yeni Python-.NET Motoruna Geçiş
Giriş
Version 26.8, Python’u .NET’e bağlayan motoru değiştirir. Çizim primitifleri aspose.slides modülüne taşındı.
Güncelleme sonrası bir sorun yaşıyorsanız doğrudan I Have an Error bölümüne gidin.
Çizim Primitifleri aspose.slides’a Taşındı
Yedi tip taşındı. İsimlerini, argümanlarını ve davranışlarını korurlar:
| Tip | 26.8 Öncesi | 26.8 ve Sonrası |
|---|---|---|
| Point | aspose.pydrawing.Point |
aspose.slides.Point |
| PointF | aspose.pydrawing.PointF |
aspose.slides.PointF |
| Size | aspose.pydrawing.Size |
aspose.slides.Size |
| SizeF | aspose.pydrawing.SizeF |
aspose.slides.SizeF |
| Rectangle | aspose.pydrawing.Rectangle |
aspose.slides.Rectangle |
| RectangleF | aspose.pydrawing.RectangleF |
aspose.slides.RectangleF |
| Color | aspose.pydrawing.Color |
aspose.slides.Color |
Bu yedi tip, aspose.pydrawing‘in geriye kalan tüm içeriğiydi. Onları yeniden yönlendirdiğinizde, kodunuzun hiçbir yerinde aspose.pydrawing referansına gerek kalmaz ve tüm import’ları kaldırılabilir. Bu aynı zamanda sonucu kontrol etmeyi de kolaylaştırır - bakınız Verify the Migration.
Eski kod:
import aspose.slides as slides
import aspose.pydrawing as drawing
with slides.Presentation() as presentation:
slide = presentation.slides[0]
shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 50, 50, 200, 100)
shape.fill_format.fill_type = slides.FillType.SOLID
shape.fill_format.solid_fill_color.color = drawing.Color.red
with slide.get_image(drawing.Size(1920, 1080)) as slide_image:
slide_image.save("slide1.jpeg", slides.ImageFormat.JPEG)
Sürüm 26.8:
import aspose.slides as slides
with slides.Presentation() as presentation:
slide = presentation.slides[0]
shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 50, 50, 200, 100)
shape.fill_format.fill_type = slides.FillType.SOLID
shape.fill_format.solid_fill_color.color = slides.Color.red
with slide.get_image(slides.Size(1920, 1080)) as slide_image:
slide_image.save("slide1.jpeg", slides.ImageFormat.JPEG)
from import biçimi aynı şekilde değişir:
# Eski kod
from aspose.pydrawing import Color, Point
# Sürüm 26.8
from aspose.slides import Color, Point
Import Hatasını Düzeltin
İzleme çıktınızı (traceback) ilk sütunda bulun.
| Hata | Neden | Düzeltme |
|---|---|---|
AttributeError: module 'aspose.pydrawing' has no attribute 'Color' (veya Point, Rectangle vb.) |
Paket 26.8, kod hâlâ eski modüle işaret ediyor | Update your code |
ImportError: cannot import name 'Color' from 'aspose.pydrawing' |
Aynı neden, from import biçimi |
Update your code |
ModuleNotFoundError: No module named 'aspose.pydrawing' |
Modül ve onun yedi tipi aspose.slides içine taşındı |
Update your code, then delete the aspose.pydrawing import |
ImportError: cannot import name 'Color' from 'aspose.slides' |
Kod taşındı, ancak kurulu paket 26.7 veya daha eski | pip install --upgrade aspose.slides |
TypeError on a color, point, or size argument |
aspose.pydrawing‘den oluşturulan bir değer yeni API’ye geçiriliyor |
Create the value from aspose.slides as well |
Kodunuzu Güncelleyin
aspose.pydrawing‘in yalnızca taşınan yedi tip dışında içeriği olmadığı için, geçiş modülün yeniden adlandırılmasıdır. Tüm import biçimleri bu tek yeniden adlandırma ile kapsanır, alias’lar dahil:
# Eski kod
import aspose.pydrawing as drawing
color = drawing.Color.red
# Sürüm 26.8 - alias çalışmaya devam ediyor
import aspose.slides as drawing
color = drawing.Color.red
Bu, bir fonksiyon gövdesi içinde de dahil olmak üzere her kapsamda geçerlidir, çünkü alias tam olarak önce bağlandığı yerde kalır. Tek dezavantajı yanıltıcı bir isim olmasıdır, bu yüzden amacı açıkça belirtmeyi düşünün:
import aspose.slides as slides
color = slides.Color.red
Kod tabanınızın büyüklüğüne uygun yaklaşımı seçin.
Manuel Değiştirme
Birkaç dosya için, aspose.pydrawing‘i arayın ve aspose.slides ile değiştirin, ardından gereksiz kalan import’ları kaldırın.
Kabuk Komutuyla Değiştirme
Bu düz metin değiştirmesidir, bu yüzden dizeler ve yorum içindeki kullanımları da etkiler. Her iki komut da değiştirilen her dosyanın bir .bak kopyasını yazar.
Linux:
grep -rlZ --include='*.py' 'aspose\.pydrawing' . \
| xargs -0 -r sed -i.bak 's/aspose\.pydrawing/aspose.slides/g'
macOS’ta sed -i '' kullanın, sed -i.bak yerine, ya da GNU sed’i gsed olarak kurun.
Windows PowerShell:
Get-ChildItem -Recurse -Filter *.py | ForEach-Object {
$t = Get-Content $_ -Raw
$new = $t -replace 'aspose\.pydrawing', 'aspose.slides'
if ($new -ne $t) {
Copy-Item $_.FullName "$($_.FullName).bak"
Set-Content $_.FullName $new -NoNewline
$_.FullName
}
}
Linux ya da macOS’ta geri almak için:
find . -name '*.py.bak' -exec sh -c 'mv "$1" "${1%.bak}"' _ {} \;
Windows’da geri almak için:
Get-ChildItem -Recurse -Filter *.py.bak | ForEach-Object {
Move-Item $_.FullName ($_.FullName -replace '\.bak$', '') -Force
}
Python Betiğiyle Değiştirme
Aynı yeniden adlandırma, Linux, macOS ve Windows’ta taşınabilir. Betik yolu bir argüman olarak alır ve --write verilmedikçe değişiklikleri önizler. --backup ekleyerek her değiştirilen dosyanın bir .bak kopyasını tutar. İstediğiniz bir adla kaydedin - kullanım mesajı çalışma zamanında adı alır.
"""aspose.pydrawing'i aspose.slides'a yeniden adlandırın. Düz metin değiştirme.
python <this script> src/ # ön izleme
python <this script> src/ --write # uygula
python <this script> src/ --write --backup # uygula, .bak kopyalarını tutarak
"""
import sys
from pathlib import Path
W = "--write" in sys.argv
B = "--backup" in sys.argv
ROOT = next((a for a in sys.argv[1:] if not a.startswith("-")), None)
if ROOT is None:
sys.exit(f"usage: python {Path(sys.argv[0]).name} <path> [--write] [--backup]")
root = Path(ROOT)
if not root.exists():
sys.exit(f"no such path: {root}")
files = [root] if root.is_file() else root.rglob("*.py")
changed = 0
for p in files:
if {".venv", "venv", "__pycache__", ".git"} & set(p.parts):
continue
s = p.read_text(encoding="utf-8")
n = s.replace("aspose.pydrawing", "aspose.slides")
if n == s:
continue
changed += 1
print(("wrote " if W else "would change ") + str(p))
if W:
if B:
p.with_suffix(p.suffix + ".bak").write_text(s, encoding="utf-8")
p.write_text(n, encoding="utf-8")
print(f"{changed} file(s) {'changed' if W else 'to change'}"
+ ("" if W or not changed else "; rerun with --write to apply"))
Tipik bir çalıştırma şu şekildedir:
$ python migrate.py src/
would change src/render.py
would change src/export/slides.py
2 file(s) to change; rerun with --write to apply
$ python migrate.py src/ --write --backup
wrote src/render.py
wrote src/export/slides.py
2 file(s) changed
Yol bir dizin olabilir, özyinelemeli olarak dolaşılır, ya da tek bir .py dosyası.
AST Tabanlı Betikle Değiştirme
Daha büyük kod tabanları için önerilir. Bu betik aynı yeniden adlandırmayı yapar, ancak her dosyayı önce ayrıştırır, böylece dizeler, yorumlar veya dokstring’lerdeki kullanımlara dokunmaz.
Modülü yerinde yeniden adlandırdığı ve alias’ları bıraktığı için, tüm import biçimleri özel durumlar olmadan işlenir: import aspose.pydrawing, import aspose.pydrawing as X, from aspose.pydrawing import Color, from aspose.pydrawing import Color as C, çok satırlı parantezli import’lar, fonksiyon içindeki import’lar ve değer olarak geçirilen modül. Aynı --write ve --backup bayraklarını kabul eder.
"""aspose.pydrawing'i aspose.slides'a yeniden adlandırın, dizeleri ve yorumları atlayarak.
python <this script> src/ # ön izleme
python <this script> src/ --write # uygula
python <this script> src/ --write --backup # uygula, .bak kopyalarını tutarak
"""
import ast, sys
from pathlib import Path
MOD, DST = "aspose.pydrawing", "aspose.slides"
W = "--write" in sys.argv
B = "--backup" in sys.argv
ROOT = next((a for a in sys.argv[1:] if not a.startswith("-")), None)
if ROOT is None:
sys.exit(f"usage: python {Path(sys.argv[0]).name} <path> [--write] [--backup]")
root = Path(ROOT)
if not root.exists():
sys.exit(f"no such path: {root}")
files = [root] if root.is_file() else root.rglob("*.py")
changed = 0
def chain(n):
p = []
while isinstance(n, ast.Attribute):
p.append(n.attr)
n = n.value
return ".".join(reversed(p + [n.id])) if isinstance(n, ast.Name) else None
def fix(src):
tree = ast.parse(src)
off, o = [], 0
for l in src.encode().splitlines(keepends=True):
off.append(o)
o += len(l)
off.append(o)
edits = []
for n in ast.walk(tree):
# import aspose.pydrawing [as X] / from aspose.pydrawing import ...
# Modül adı yerinde yeniden adlandırılır, böylece mevcut takma adlar aynı şekilde kalır.
if (isinstance(n, ast.Import) and any(a.name == MOD for a in n.names)) or \
(isinstance(n, ast.ImportFrom) and n.module == MOD):
s, e = off[n.lineno - 1], off[n.end_lineno - 1] + n.end_col_offset
edits.append((s, e, src.encode()[s:e].decode().replace(MOD, DST)))
# Modüle referans yapan herhangi bir ifade, çıplak `fn(aspose.pydrawing)` dahil.
elif isinstance(n, ast.Attribute) and chain(n) == MOD:
edits.append((off[n.lineno - 1] + n.col_offset,
off[n.end_lineno - 1] + n.end_col_offset, DST))
b = src.encode()
for s, e, r in sorted(edits, reverse=True): # sondan başa doğru işlemek offset'leri geçerli tutar
b = b[:s] + r.encode() + b[e:]
return b.decode()
for p in files:
if {".venv", "venv", "__pycache__", ".git"} & set(p.parts):
continue
s = p.read_text(encoding="utf-8")
try:
n = fix(s)
except SyntaxError as e:
print(f"skipped {p}: {e}")
continue
if n != s:
print(("wrote " if W else "would change ") + str(p))
if W:
if B:
p.with_suffix(p.suffix + ".bak").write_text(s, encoding="utf-8")
p.write_text(n, encoding="utf-8")
Her iki betik de idempotent’tir: taşınmış kodda tekrar çalıştırıldıklarında hiçbir şey değişmez.
Geçişi Doğrulama
Metin araması, herhangi bir kalıntı olup olmadığını gösterir:
grep -rn 'aspose\.pydrawing' --include='*.py' --exclude-dir=.venv .
Bu hızlıdır, ancak dizeler ve yorumlar içinde de eşleşir, bu yüzden temiz kod bile eşleşme üretebilir. Kesin bir cevap için aşağıdaki kontrolü kullanın. Yalnızca gerçek kod referanslarını raporlar ve kalıntı varsa sıfır olmayan bir durum kodu ile çıkar, bu da onu bir derleme aşaması olarak kullanılabilir kılar.
import ast, sys
from pathlib import Path
MOD = "aspose.pydrawing"
ROOT = next((a for a in sys.argv[1:] if not a.startswith("-")), ".")
def chain(n):
p = []
while isinstance(n, ast.Attribute):
p.append(n.attr)
n = n.value
return ".".join(reversed(p + [n.id])) if isinstance(n, ast.Name) else None
def scan(tree):
for n in ast.walk(tree):
if isinstance(n, ast.Import) and any(a.name == MOD for a in n.names):
yield n.lineno, f"import {MOD}"
elif isinstance(n, ast.ImportFrom) and n.module == MOD:
names = ", ".join(a.name for a in n.names)
yield n.lineno, f"from {MOD} import {names}"
elif isinstance(n, ast.Attribute) and chain(n) == MOD:
yield n.lineno, f"reference to {MOD}"
hits = 0
for p in sorted(Path(ROOT).rglob("*.py")):
if {".venv", "venv", "__pycache__", ".git"} & set(p.parts):
continue
try:
tree = ast.parse(p.read_text(encoding="utf-8"))
except SyntaxError as e:
print(f"skipped {p}: {e}")
continue
for lineno, what in sorted(scan(tree)):
print(f"{p}:{lineno}: {what}")
hits += 1
print("migration complete" if not hits else f"{hits} reference(s) left")
sys.exit(1 if hits else 0)
Geçişten önce ve sonra çalıştırın:
$ python verify.py src/
src/render.py:4: from aspose.pydrawing import Color, Point
src/render.py:11: import aspose.pydrawing
src/render.py:12: reference to aspose.pydrawing
3 reference(s) left
$ python migrate.py src/ --write
wrote src/render.py
$ python verify.py src/
migration complete
Son olarak, taşınan tipleri kullanan bir smoke test çalıştırın:
import aspose.slides as slides
with slides.Presentation() as presentation:
slide = presentation.slides[0]
shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 50, 50, 200, 100)
shape.fill_format.fill_type = slides.FillType.SOLID
shape.fill_format.solid_fill_color.color = slides.Color.red
presentation.save("smoke.pptx", slides.export.SaveFormat.PPTX)
print("OK")
Önerilen Geçiş Sırası
- Bir temel kaydedin. Mevcut sürümde testlerinizi çalıştırın ve referans render’ları saklayın. Bu, geçiş hatalarını sonraki render farklılıklarından ayırmanıza olanak tanır.
- Geçişi önizleyin. Betiklerden birini
--writeolmadan çalıştırın ve değiştireceği dosya listesini inceleyin. - Uygulayın ve doğrulayın.
--write --backupile çalıştırın, ardından doğrulama betiğini ve smoke test’i yürütün. - Render’ları toleransla karşılaştırın. .NET 6 derlemesine geçiş, metin ve efektlerde küçük farklılıklar oluşturabilir. Byte bazlı kontrol yerine eşik tabanlı bir karşılaştırma kullanın.
- Yedekleri silin. Sonuç onaylandığında
.bakdosyalarını silin: Linux ve macOS’tafind . -name '*.py.bak' -delete, Windows’taGet-ChildItem -Recurse -Filter *.py.bak | Remove-Item.
Tek Kod Tabanında Her İki Sürümü de Destekleme
Aynı kaynak kodundan 26.7 ve 26.8 ile çalışmanız gerekiyorsa:
try:
from aspose.slides import Color, Point, Rectangle # 26.8 ve sonrası
except ImportError:
from aspose.pydrawing import Color, Point, Rectangle # 26.7 ve öncesi
Değişmeyenler
- Taşınan primitiflerin adları, argümanları ve davranışları.
aspose.slidesAPI’sinin geri kalan kısmı.- Lisanslama ve lisans dosyasının uygulanma şekli.
- Dosya formatları ve kaydetme/yükleme davranışı.
- Windows ve macOS üzerindeki sistem gereksinimleri.
- Ayrı bir .NET kurulumunun olmaması - çalışma zamanı hâlâ paketlenmiş.