सामग्री के माध्यम से पुनरावृत्ति करते समय नोड संपत्ति कोई नहीं है तो कैसे जांचें?

Aug 17 2020

मैं कुछ मिश्रण फ़ाइलों में नोड्स और नोडग्रुप के माध्यम से पुनरावृत्ति करते हुए एक बिना किसी त्रुटि के चल रहा हूं।

त्रुटि: गुण

अगर वस्तुओं का कोई 'नाम' संपत्ति नहीं है और इसे छोड़ दूं तो मैं कैसे जांचूंगा?

   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':

जवाब

3 batFINGER Aug 17 2020 at 17:41

एक विशेषता हो सकती है 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")
0451 Aug 17 2020 at 04:14

रॉन जेन्सेंस की टिप्पणी के आधार पर:

    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':