सामग्री के माध्यम से पुनरावृत्ति करते समय नोड संपत्ति कोई नहीं है तो कैसे जांचें?
मैं कुछ मिश्रण फ़ाइलों में नोड्स और नोडग्रुप के माध्यम से पुनरावृत्ति करते हुए एक बिना किसी त्रुटि के चल रहा हूं।
त्रुटि: गुण
अगर वस्तुओं का कोई 'नाम' संपत्ति नहीं है और इसे छोड़ दूं तो मैं कैसे जांचूंगा?
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':
जवाब
एक विशेषता हो सकती है None
त्रुटि NoneType has no attribute
ब्लेंडर स्क्रिप्टिंग में देखी गई एक सामान्य त्रुटि है। उदाहरण के लिए यह मामला हो सकता हैcontext.object is None
ओपी को इस त्रुटि संदेश को और अधिक प्रतिबिंबित करने के लिए प्रश्न के शीर्षक को संपादित करने की सिफारिश करेंगे।
Error: AttributeError: 'NoneType' object has no attribute 'name'
द्वारा node.node_tree.name == 'NodeGroupName'
सूचित node.node_tree
किया गया मूल्य है None
। इस मामले के लिए परीक्षण कर सकते हैं, यानी
if node.node_tree is None:
विरोध के रूप में
if hasattr(node, "node_tree"):
नोड ट्री होने पर दोनों सही होंगे None
यह वास्तव में एक अजीब मामला है कि प्रश्न में कोड इस त्रुटि को फेंक देगा, क्योंकि मुझे पता नहीं है (अभी तक) कि कैसे एक समूह नोड को जोड़ा जाए और कोई नोड से जुड़ा नहीं है। अटकलें यह एक नोड समूह को हटाने का परिणाम है bpy.data.node_groups
कि एक सामग्री नोड पेड़ का एक नोड था ..
इसलिए प्रश्न स्क्रिप्ट की अंतिम पंक्ति हो सकती है
if (node.type in ["GROUP"]
and node.node_tree
and node.node_tree.name == 'NodeGroupName'
):
के बाद से पीछा और पहले बंद हो जाता है False
का उपयोग करते हुए getattr
चूंकि हम तीसरे तर्क डिफ़ॉल्ट के साथ विशेषता प्राप्त करने का उपयोग करके या तो उसी के साथ व्यवहार करेंगे
node_tree = getattr(node, "node_tree", None)
None
दोनों मामलों में होगा । IMO इस "ट्रम्प्स" में दोनों नोड ट्री का उपयोग करते हैं, फिर नाम विशेषता परीक्षण होता है। None
कुछ भी नहीं है, अगर हम जानते हैं कि यह विशेषताओं के लिए आगे कोई परीक्षण नहीं है, तो यह प्रतीत होता है कि यह अतिश्योक्तिपूर्ण हो सकता है यह भी सुनिश्चित कर सकता है कि यदि नोड पेड़ नहीं None
है तो इसका एक नाम होगा ।bpy.types.ShaderNodeTree.name
टेस्ट स्क्रिप्ट
नोड के 'GROUP'
प्रकार के लिए "डबल टेस्ट" के साथ ऊपर का उपयोग करके चेक करें कि इसमें कोई भी नॉन नोड ट्री नहीं है।
एक शब्दकोश बनाएं, जिसमें कुंजी मिलान वाले नोड समूह का नाम है जिसमें सामग्री का नाम, नोड नाम टुपल्स की सूची है।
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)
आउटपुट।
1 नोड समूह "Test_Material", 2 सामग्री "TestMat" और "TestMat.001" के साथ फ़ाइल।
नोड समूह का उपयोग दोनों सामग्रियों में "समूह" नाम के साथ दोनों सामग्रियों में किया जाता है।
['Test_Material']
defaultdict(<class 'list'>, {'Test_Material': [('TestMat', 'Group'), ('TestMat.001', 'Group')]})
टिप्पणियाँ:
परीक्षणों में True
या उसके बराबर होने से सावधान रहें False
। डिफ़ॉल्ट रूप से अजगर सत्य या असत्य के लिए अधिकांश प्रकारों की बराबरी करता है। झूठे के कुछ उदाहरण हैं None
, पूर्णांक 0
और एक खाली सूची[]
जैसे तरीके hasattr
वापसी या तो True
याFalse
if hasattr(foo, "bar") == True:
यदि foo.bar
यह मौजूद है तो कुछ हद तक यह पढ़ता है
if True == True:
इसके बजाय बस का उपयोग करें
if hasattr(foo, "bar"):
बूलियन झूठे को वापस करने के लिए थोड़ा ऊपर बदलना जब नोड में कोई नोड_ट्री विशेषता नहीं है, if nt:
तो दोनों मामलों में गलत होगा, लेकिन हम दोनों के बीच विचार कर सकते हैं।
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")
रॉन जेन्सेंस की टिप्पणी के आधार पर:
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':