Bagaimana cara memeriksa apakah properti node bukan None saat melakukan iterasi melalui material?
Saya mengalami kesalahan tanpa atribut saat melakukan iterasi melalui node dan nodegroups di beberapa file campuran.
Kesalahan: AttributeError: Objek 'NoneType' tidak memiliki atribut 'nama'
Bagaimana cara memeriksa apakah objek tidak memiliki properti 'nama' dan melewatinya?
for mat in bpy.data.materials:
if mat.use_nodes == True:
for node in mat.node_tree.nodes:
#check if no has attribute name
if node.type in ["GROUP"] and node.node_tree.name == 'NodeGroupName':
Jawaban
Atribut bisa None
Kesalahan NoneType has no attribute
ini adalah kesalahan umum yang terlihat pada skrip blender. Misalnya bisa jadi itu kasusnyacontext.object is None
Untuk OP akan merekomendasikan mengedit judul pertanyaan untuk mencerminkan pesan kesalahan ini lebih-lebih.
Error: AttributeError: 'NoneType' object has no attribute 'name'
yang dilemparkan node.node_tree.name == 'NodeGroupName'
adalah menginformasikan node.node_tree
memiliki nilai None
. Dapat menguji untuk kasus ini, yaitu
if node.node_tree is None:
sebagai lawan
if hasattr(node, "node_tree"):
Keduanya akan benar ketika pohon simpul berada None
Sebenarnya adalah kasus yang aneh bahwa kode yang dimaksud akan menampilkan kesalahan ini, karena saya belum mengetahui (belum) tentang cara menambahkan node grup dan tidak memiliki node_tree yang terhubung. Berspekulasi bahwa ini adalah hasil dari menghapus grup node dari bpy.data.node_groups
yang merupakan node dari pohon node material ..
karenanya baris terakhir dari skrip pertanyaan bisa jadi
if (node.type in ["GROUP"]
and node.node_tree
and node.node_tree.name == 'NodeGroupName'
):
sejak merantai dan berhenti dulu False
Menggunakan getattr
Karena kami akan memperlakukan baik menggunakan atribut get yang sama dengan default argumen ketiga
node_tree = getattr(node, "node_tree", None)
akan berada None
dalam kedua kasus tersebut. IMO ini "mengalahkan" menggunakan kedua pohon simpul has kemudian tes atribut nama. None
tidak memiliki apa-apa, jika kita tahu tidak ada pengujian lebih lanjut untuk atribut akan tampak berlebihan. Dapat juga memastikan bahwa jika pohon simpul tidak, None
ia akan memiliki nama .bpy.types.ShaderNodeTree.name
Uji skrip
Menggunakan di atas dengan "tes ganda" untuk sebuah node yang 'GROUP'
bertipe periksa itu memiliki pohon node bukan tidak ada.
Buatlah kamus, dengan kunci yang cocok dengan nama grup node yang berisi daftar nama material, nama node tupples.
import bpy
from bpy import data
from collections import defaultdict
# all the group nodes in blendfile
print(data.node_groups.keys())
group_nodes = defaultdict(list)
# create a look up dictionary
for m in data.materials:
if m.use_nodes:
for n in m.node_tree.nodes:
nt = getattr(n, "node_tree", None)
if nt and n.type == 'GROUP':
group_nodes[nt.name].append((m.name, n.name))
print(group_nodes)
Keluaran.
File dengan 1 grup node "Test_Material", 2 material "TestMat" dan "TestMat.001".
Grup node digunakan di kedua materi dengan nama "Grup" di keduanya.
['Test_Material']
defaultdict(<class 'list'>, {'Test_Material': [('TestMat', 'Group'), ('TestMat.001', 'Group')]})
Catatan:
Waspadalah dalam menyamakan True
atau False
dalam ujian. Secara default python menyamakan sebagian besar tipe dengan True atau false. Beberapa contoh salah adalah None
, bilangan bulat 0
dan daftar kosong[]
Metode seperti hasattr
return baik True
atauFalse
if hasattr(foo, "bar") == True:
jika foo.bar
ada ini dibaca agak mirip dengan
if True == True:
alih-alih cukup gunakan
if hasattr(foo, "bar"):
Mengubah sedikit di atas untuk mengembalikan boolean false alih-alih tidak ada ketika node tidak memiliki atribut node_tree, if nt:
akan menjadi salah dalam kedua kasus, tetapi kita dapat membedakan keduanya.
nt = getattr(n, "node_tree", False)
if nt and n.type == 'GROUP':
group_nodes[nt.name].append((m.name, n.name))
if nt is None:
print(f"{m.name}:{n.name} node_tree is None")
Berdasarkan komentar Ron Jensens:
for mat in bpy.data.materials:
if mat.use_nodes == True:
for node in mat.node_tree.nodes:
if hasattr(node, 'node_tree') == True:
if hasattr(node.node_tree, 'name') == True:
if node.type in ["GROUP"] and node.node_tree.name == 'NodeGroupName':